Sayfa 1

Sayfa 2
KAVRAMLARI
PROGRAMLAMA DİLLERİ
ONUNCU BASKI

Sayfa 3
Bu sayfa bilerek boş bırakılmıştır

Sayfa 4
KAVRAMLARI
PROGRAMLAMA DİLLERİ
ONUNCU BASKI
ROBERT W. SEBESTA
Colorado Springs'deki Colorado Üniversitesi
Boston Columbus Indianapolis New York San Francisco Upper Saddle Nehri
Amsterdam Cape Town Dubai Londra Madrid Milano Münih Paris Montreal Toronto
Delhi Mexico City Sao Paulo Sidney Hong Kong Seul Singapur Taipei Tokyo

Sayfa 5
ECS Başkan Yardımcısı ve Yazı İşleri Müdürü:
Marcia Horton
Genel Yayın Yönetmeni: Michael Hirsch
Genel Yayın Yönetmeni: Matt Goldstein
Yazı İşleri Asistanı: Chelsea Kharakozova
Başkan Yardımcısı Pazarlama: Patrice Jones
Pazarlama Müdürü: Yez Alayan
Pazarlama Koordinatörü: Kathryn Ferranti
Pazarlama Asistanı: Emma Snider
Başkan Yardımcısı ve Üretim Direktörü:
Vince O'Brien
Genel Yayın Yönetmeni: Jeff Holcomb
Kıdemli Üretim Proje Yöneticisi: Marilyn Lloyd
Üretim Müdürü: Nick Sklitsis
Operasyon Uzmanı: Lisa McDowell
Kapak Tasarımcısı: Anthony Gemmellaro
Metin Tasarımcısı: Gillian Hall
Kapak Resmi: Pisac, Peru yakınlarındaki dağ;
Yazarın fotoğrafı
Medya Editörü: Dan Sandin
Tam Hizmet Sağlayıcı: Laserwords
Proje Yönetimi: Gillian Hall
Yazıcı/Klasör: Courier Westford
Kapak Yazıcısı: Lehigh-Phoenix Color
Bu kitap InDesign'da yazılmıştır. Bazal yazı tipi Janson Text'dir. Ekran yazı tipi ITC Franklin Gothic'tir.
Telif Hakkı © 2012, 2010, 2008, 2006, 2004 Pearson Education, Inc., Addison-Wesley olarak yayınlamaktadır.
Her hakkı saklıdır. Amerika Birleşik Devletleri'nde üretilmiştir. Bu yayın Kopyalama ile korunmaktadır.
haktır ve yasaklanmış herhangi bir çoğaltma, saklama işlemi öncesinde yayıncıdan izin alınmalıdır.
bir erişim sisteminde veya herhangi bir biçimde veya herhangi bir yolla, elektronik, mekanik, fotokopi,
kayıt veya benzer şekilde. Bu çalışmadaki materyali kullanmak için izin(ler) almak için lütfen yazılı bir
Pearson Education, Inc., Permissions Department, One Lake Street, Upper Saddle River, New'e talep
Jersey 07458 veya talebinizi 201-236-3290'a fakslayabilirsiniz.
Üreticiler ve satıcılar tarafından ürünlerini ayırt etmek için yapılan tanımlamaların birçoğunun ticari olduğu iddia edilmektedir.
işaretler. Bu kitapta bu tanımlamaların yer aldığı ve yayıncının bir ticari marka talebinden haberdar olduğu durumlarda,
atamalar ilk büyük harfle veya tamamı büyük harfle basılmıştır.
Kongre Kütüphanesi Yayın Verilerini Kataloglama
Sebesta, Robert W.
Programlama dilleri kavramları / Robert W. Sebesta.—10. baskı.
P. santimetre.
Bibliyografik referanslar ve dizin içerir.
ISBN 978-0-13-139531-2 (alk. kağıt)
1. Programlama dilleri (Elektronik bilgisayarlar) I. Başlık.
QA76.7.S43 2009
005.13—dc22
2008055702
10 9 8 7 6 5 4 3 2 1
ISBN 10: 0-13-139531-9
ISBN 13: 978-0-13-139531-2

Sayfa 6
Onuncu Baskıda Yeni
Bölüm 5: fonksiyonel pro-
gramer dilleri eklendi
Bölüm 6: COBOL'un kayıt işlemleriyle ilgili bölüm kaldırıldı;
F#'da listeler, demetler ve birleşimlerle ilgili yeni bölümler eklendi
8. Bölüm: Fortran'ın Do ifadesinin tartışmaları ve Ada'nın davası
ifade kaldırıldı; içindeki kontrol ifadelerinin açıklamaları
fonksiyonel programlama dilleri bu bölüme taşınmıştır.
15. Bölüm
Bölüm 9: kapatmalar hakkında yeni bir bölüm, alt arama hakkında yeni bir bölüm
dolaylı olarak programlar ve F#'daki genel işlevler üzerine yeni bir bölüm
katma; Ada'nın genel alt programlarının açıklaması kaldırıldı
Bölüm 11: Objective-C ile ilgili yeni bir bölüm eklendi, bölüm
önemli ölçüde revize edildi
Bölüm 12: Objective-C ile ilgili yeni bir bölüm eklendi, beş yeni şekil
ureler eklendi
Bölüm 13: işlevsel programlamada eşzamanlılık üzerine bir bölüm
diller eklendi; Ada'nın asenkron mesajının tartışılması
geçiş kaldırıldı
Bölüm 14: C# olay işleme üzerine bir bölüm eklendi
Bölüm 15: F# ile ilgili yeni bir bölüm ve destek hakkında yeni bir bölüm
öncelikli olarak zorunlu dillerde işlevsel programlama eklendi;
fonksiyonel programlamada birkaç farklı yapının tartışmaları
diller Bölüm 15'ten önceki bölümlere taşındı

Sayfa 7
vi
önsöz
Onuncu Baskı için Değişiklikler
T o gol, genel yapısı ve bu onuncu baskısının yaklaşım Kavramları
Programlama Dillerinin sayısı dokuz kulağınkiyle aynı kalır.
lier sürümleri. Temel hedefler, ana yapıları tanıtmaktır.
çağdaş programlama dillerinin ve okuyucunun
Mevcut ve gelecekteki programlamanın eleştirel değerlendirmesi için gerekli araçlar
Diller. İkincil bir amaç ise okuyucuyu bilişim araştırmalarına hazırlamaktır.
programlama dilinin derinlemesine bir tartışmasını sağlayarak piler tasarımı
yapılar, sözdizimini tanımlamanın resmi bir yöntemini sunma ve tanıtma
sözcüksel ve sözdizimsel çözümleme yaklaşımları.
Onuncu baskı, dokuzuncu baskıdan birkaç farklı türe doğru evrilmiştir.
değişikliklerden. Malzemenin güncelliğini korumak için, tartışmanın bir kısmı
eski programlama dilleri kaldırıldı. Örneğin, tarif-
COBOL'un kayıt operasyonları Bölüm 6'dan kaldırıldı ve
Fortran'ın Do ifadesi Bölüm 8'den kaldırıldı.
Ada'nın genel alt programlarının bir kısmı Bölüm 9'dan kaldırıldı ve tartışma
Ada'nın asenkron mesaj geçişi, Bölüm 13'ten kaldırıldı.
Öte yandan, kapanışlarla ilgili bir bölüm, alt programların çağrılmasıyla ilgili bir bölüm
dolaylı olarak ve Bölüm 9'a F#'daki genel işlevler hakkında bir bölüm eklendi;
Objective-C ile ilgili bölümler Bölüm 11 ve 12'ye eklendi; konu ile ilgili bir bölüm
fonksiyonel programlama dillerinde para birimi Bölüm 13'e eklendi; a
Bölüm 14'e C# olay işleme bölümü eklendi; F# ile ilgili bir bölüm ve
öncelikli olarak zorunlu dilde işlevsel programlama desteği hakkında bir bölüm
Bölüm 15'e ölçüler eklendi.
Bazı durumlarda, malzeme taşındı. Örneğin, birkaç farklı
fonksiyonel programlama dillerindeki yapıların tartışmaları taşındı
15. Bölümden önceki bölümlere. Bunlar arasında, açıklamaları da vardı.
Fonksiyonel programlama dillerindeki kontrol ifadeleri Bölüm 8'e ve
Bölüm 6'daki Şema ve ML'nin listeleri ve liste işlemleri. Bu hareketler şunları gösterir:
kitabın felsefesinde önemli bir değişim - bir anlamda
fonksiyonel programlama dillerinin bazı yapılarının önceki
sürümleri, işlevsel programlama dili yapılarının tüm tartışmaları
Bölüm 15'te ayrılmıştır.
11, 12 ve 15. Bölümler önemli ölçüde revize edildi ve beş rakam verildi.
12. bölüme eklendi.
Son olarak, çok sayıda bölümde çok sayıda küçük değişiklik yapıldı.
kitabın, öncelikle netliği artırmak için.

Sayfa 8
Vizyon
Bu kitap, programlama dillerinin temel kavramlarını şu şekilde açıklamaktadır:
çeşitli dil yapılarının tasarım konularını tartışmak,
en yaygın dillerden bazılarında bu yapılar için tasarım seçenekleri,
ve tasarım alternatiflerini eleştirel olarak karşılaştırma.
Programlama dilleriyle ilgili herhangi bir ciddi çalışma, aşağıdakilerin incelenmesini gerektirir:
aralarında sözdizimini tanımlamanın resmi yöntemleri olan bazı ilgili konular
ve Bölüm 3'te ele alınan programlama dillerinin semantiği.
Ayrıca, çeşitli dil yapıları için uygulama teknikleri birbiriyle uyumlu olmalıdır.
taraflı: Sözcüksel ve sözdizimi analizi Bölüm 4'te tartışılmıştır ve
alt program bağlantısının anlatılması Bölüm 10'da ele alınmaktadır.
diğer bazı dil yapıları kitabın çeşitli bölümlerinde tartışılmaktadır.
Aşağıdaki paragraflar onuncu baskının içeriğini özetlemektedir.
Bölüm Anahatları
Bölüm 1, programlama dillerini incelemek için bir gerekçe ile başlar. o zaman
Programlama dillerini ve dilini değerlendirmek için kullanılan kriterleri tartışır
yapılar. Dil tasarımı üzerindeki birincil etkiler, ortak tasarım ticareti-
izinler ve uygulamaya yönelik temel yaklaşımlar da incelenmektedir.
Bölüm 2, önemli dillerin çoğunun evrimini özetlemektedir.
bu kitapta küfür etti. Hiçbir dil tam olarak tanımlanmasa da kökenleri,
amaçları ve her birinin katkıları tartışılmıştır. Bu tarihsel bakış,
değerlidir, çünkü konuyu anlamak için gerekli arka planı sağlar.
çağdaş dil tasarımı için pratik ve teorik temel. Aynı zamanda moti-
Dil tasarımı ve değerlendirmesi üzerine daha fazla çalışma vates. Ayrıca, çünkü hiçbiri
Kitabın geri kalanı Bölüm 2'ye bağlıdır, kendi başına okunabilir,
diğer bölümlerden bağımsızdır.
Bölüm 3, sözdizimini tanımlamak için birincil resmi yöntemi açıklar
programlama dili - BNF. Bunu, özniteliğin bir açıklaması izler
dillerin hem sözdizimini hem de statik anlambilimini tanımlayan dilbilgisi.
Anlamsal betimlemenin zor görevi, daha sonra kısa açıklamalar da dahil olmak üzere keşfedilir.
en yaygın üç yönteme giriş: operasyonel, düz anlam,
ve aksiyomatik anlambilim.
Bölüm 4, sözcük ve sözdizimi analizini tanıtır. Bu bölüm hedefleniyor
müfredatlarında artık bir derleyici tasarım dersi gerektirmeyen kolejler.
2. Bölüm gibi, bu bölüm de bağımsızdır ve metinden bağımsız olarak okunabilir.
kitabın geri kalanı.
Bölüm 5'ten 14'e kadar olan bölümler, birincil için tasarım konularını ayrıntılı olarak açıklamaktadır.
programlama dillerinin yapıları. Her durumda, birkaç için tasarım seçenekleri
örnek diller sunulur ve değerlendirilir. Özellikle, Bölüm 5 şunları kapsar:
değişkenlerin birçok özelliği, Bölüm 6 veri türlerini kapsar ve Bölüm 7
İfadeleri ve atama ifadelerini açıklar. Bölüm 8 kontrolü açıklar
önsöz vii

Sayfa 9
viii
önsöz
açıklamalar ve Bölüm 9 ve 10 alt programları ve bunların uygulanmasını tartışır.
tion. Bölüm 11, veri soyutlama olanaklarını inceler. 12. Bölüm, bir
nesne yönelimli programlamayı destekleyen dil özelliklerinin derinlemesine tartışılması
(kalıtım ve dinamik yöntem bağlama), Bölüm 13 eşzamanlılığı tartışır
program birimleridir ve Bölüm 14, kısa bir açıklama ile birlikte istisna işleme hakkındadır.
olay işleme tartışması.
Son iki bölüm (15 ve 16), en önemli alternatiflerden ikisini tanımlamaktadır.
tive programlama paradigmaları: fonksiyonel programlama ve mantıksal programlama.
Bununla birlikte, fonksiyonel pro- syonların bazı veri yapıları ve kontrol yapıları,
gramer dilleri 6. ve 8. Bölümlerde tartışılmaktadır.
bazı ilkel işlevlerinin açıklamaları da dahil olmak üzere Scheme'e giriş,
özel formlar ve fonksiyonel formlar ve ayrıca bazı basit işlev örnekleri.
Şemada yazılanlar. ML, Haskell ve F# ile ilgili kısa tanıtımlar verilmiştir
işlevsel dil tasarımında bazı farklı yönleri göstermek için. 16. Bölüm
mantık programlamayı ve mantık programlama dili olan Prolog'u tanıtır.
Eğitmene
Colorado Üniversitesi'ndeki genç seviye programlama dili kursunda
Colorado Springs'te kitap şu şekilde kullanılır: Genellikle 1. Bölümleri ele alırız.
ve 3 ayrıntılı olarak ve öğrenciler okumayı ilginç ve faydalı bulsalar da,
Bölüm 2, zor teknik içerik eksikliğinden dolayı çok az ders süresi alır.
Çünkü sonraki bölümlerdeki hiçbir materyal, belirtildiği gibi Bölüm 2'ye bağlı değildir.
daha önce, tamamen atlanabilir ve derleyicide bir kursa ihtiyacımız olduğu için
tasarım, Bölüm 4 kapsanmamaktadır.
5'ten 9'a kadar olan bölümler, kapsamlı bilgi birikimine sahip öğrenciler için nispeten kolay olmalıdır.
C++, Java veya C# programlama deneyimi. 10'dan 14'e kadar olan bölümler daha fazla
zorlayıcıdır ve daha ayrıntılı dersler gerektirir.
15. ve 16. Bölümler, ortaokul düzeyindeki çoğu öğrenci için tamamen yenidir.
İdeal olarak, Scheme ve Prolog için dil işlemcileri aşağıdakiler için mevcut olmalıdır:
öğrencilerin bu bölümlerdeki materyalleri öğrenmeleri gerekmektedir. Yeterli malzeme
öğrencilerin bazı basit programlarla uğraşmalarını sağlamak için dahil edilmiştir.
Lisans dersleri muhtemelen tüm dersleri kapsayamayacak-
son iki bölümde riyal. Ancak lisansüstü dersler,
kısımlarını atlayarak bu bölümlerdeki materyali tamamen tartışın.
zorunlu diller üzerine erken bölümler.
Ek Malzemeler
Aşağıdaki ekleri bu kitabın tüm okuyucuları www.
.pearsonhighered.com/cssupport .
• Bir dizi ders notu slaytı. Her bölüm için PowerPoint slaytları mevcuttur
kitapta.
• Kitaptaki tüm şekilleri içeren PowerPoint slaytları.

Sayfa 10
Kitaba eşlik eden bir Web sitesi şu adreste mevcuttur: www.pearsonhighered.com/sebe-
sta . Bu sitede mini kılavuzlar (yaklaşık 100 sayfalık eğitimler) bulunmaktadır.
bir avuç dil. Bunlar öğrencinin bildiği varsayımıyla ilerler.
öğrenciye yeterli bilgiyi vererek başka bir dilde nasıl programlanacağını
Her dilde bölüm materyallerini tamamlamak için. Şu anda site
C++, C, Java ve Smalltalk için kılavuzlar içerir.
Sorun setlerinin çoğuna yönelik çözümler, kalifiye eğitimciler tarafından mevcuttur.
www.pearsonhighered.com/irc adresindeki Eğitmen Kaynak Merkezimizde.
Lütfen okulunuzun Pearson Education temsilcisiyle iletişime geçin veya adresini ziyaret edin.
www.pearsonhighered.com/irc kayıt olmak için.
Dil İşlemci Kullanılabilirliği
Bazı programlama dilleri için işlemciler ve bilgiler
Bu kitapta tartışılan aşağıdaki Web Sitelerinde bulunabilir:
C, C++, Fortran ve Ada
gcc.gnu.org
C# ve F#
microsoft.com
Java
java.sun.com
Haskell
haskell.org
Lua
www.lua.org
şema
www.plt-scheme.org/software/drscheme
Perl
www.perl.com
piton
www.python.org
yakut
www.ruby-lang.org
JavaScript hemen hemen tüm tarayıcılarda bulunur; PHP hemen hemen tüm
Web sunucuları.
Tüm bu bilgiler, eşlik eden Web Sitesinde de yer almaktadır.
Teşekkür
Seçkin yorumcuların önerileri buna büyük ölçüde katkıda bulundu.
kitabın şimdiki hali. Alfabetik sıraya göre bunlar:
Matthew Michael Burke
ping Chu
DePaul Üniversitesi
Teresa Cole
Boise Eyalet Üniversitesi
Pamela Kesici
Kalamazoo Koleji
Amer Divan
Colorado Üniversitesi
Stephen Edwards
Virginia Teknolojisi
David E. Goldschmidt
Nigel Gwee
Güney Üniversitesi – Baton Rouge
Önsöz ix

Sayfa 11
x
önsöz
Timothy Henry
Rhode Island Üniversitesi
Paul M. Jackowitz
Scranton Üniversitesi
Duane J. Jarc
Maryland Üniversitesi, Üniversite Koleji
KN Kral
Georgia Eyalet Üniversitesi
Donald Kraft
Louisiana Eyalet Üniversitesi
Simon H. Lin
California Eyalet Üniversitesi-Northridge
Mark Llewellyn
Merkez Florida Üniversitesi
Bruce R.Maxim
Michigan Üniversitesi – Dearborn
Robert McCloskey
Scranton Üniversitesi
Curtis Çayırı
Maine Üniversitesi
Gloria Melara
California Eyalet Üniversitesi-Northridge
Frank J. Mitropoulos
Nova Güneydoğu Üniversitesi
Euripides Montagne
Merkez Florida Üniversitesi
Serita Neleşen
Calvin Koleji
Bob Neufeld
Wichita Eyalet Üniversitesi
Charles Nicholas
Maryland-Baltimore County Üniversitesi
Tim R. Norton
Colorado-Colorado Springs Üniversitesi
Richard M. Osborne
Colorado-Denver Üniversitesi
Saverio Perugini
Dayton Üniversitesi
Walter Pharr
Charleston Koleji
Michael Prentice
SUNY Bufalo
Amar Raheja
California Eyalet Politeknik Üniversitesi – Pomona
Hüseyin Saidyan
Kansas Üniversitesi
Stuart C. Shapiro
SUNY Bufalo
Neelam Soundarajan
Ohio Devlet Üniversitesi
ryan stansifer
Florida Teknoloji Enstitüsü
Nancy Tinkham
Rowan Üniversitesi
Paul Tymann
Rochester Teknoloji Enstitüsü
Cristian Videira Lopes
Kaliforniya Üniversitesi-Irvine
Sumanth Yenduri
Güney Mississippi Üniversitesi
Salih Yurttaş
Teksas A&M Üniversitesi
Daha önceki baskılar için çok sayıda başka kişi girdi sağladı.
Gelişiminin çeşitli aşamalarında Programlama Dilleri Kavramları . Herşey
onların yorumları faydalıydı ve büyük beğeni topladı. Alfabetik sıraya göre,
Bunlar: Vicki Allan, Henry Bauer, Carter Bays, Manuel E. Bermudez, Peter
Brouwer, Margaret Burnett, Paosheng Chang, Liang Cheng, John Crenshaw,
Charles Dana, Barbara Ann Griem, Mary Lou Haag, John V. Harrison, Eileen
Head, Ralph C. Hilzer, Eric Joanis, Leon Jololian, Hikyoo Koh, Jiang B. Liu,
Meiliu Lu, Jon Mauney, Robert McCoard, Dennis L. Mumaugh, Michael G.
Murphy, Andrew Oldroyd, Young Park, Rebecca Parsons, Steve J. Phelps,
Jeffery Popyack, Raghvinder Sangwan, Steven Rapkin, Hamilton Richard,
Tom Sager, Joseph Schell, Sibylle Schupp, Mary Louise Soffa, Neelam
Soundarajan, Ryan Stansifer, Steve Stevenson, Virginia Teller, Yang Wang,
John M. Weiss, Franck Xia ve Salih Yurnas.

Sayfa 12
Matt Goldstein, editör; Chelsea Kharakozova, editör yardımcısı; ve,
Addison-Wesley'in kıdemli üretim müdürü Marilyn Lloyd ve Gillian
The Aardvark Group Yayıncılık Hizmetleri Salonu, hepsi minnettarlığımı hak ediyor.
onuncu baskıyı hem hızlı hem de dikkatli bir şekilde üretme çabaları.
yazar hakkında
Robert Sebesta, Bilgisayar Bilimleri alanında Fahri Doçenttir.
Colorado-Colorado Springs Üniversitesi'nde Bölüm. Profesör Sebesta
Boulder'daki Colorado Üniversitesi'nden uygulamalı matematik alanında lisans derecesi aldı
ve Pennsylvania Eyalet Üniversitesi'nden bilgisayar bilimlerinde yüksek lisans ve doktora dereceleri.
38 yıldan fazla bir süredir bilgisayar bilimi dersleri veriyor. Mesleki ilgi alanları
programlama dillerinin tasarımı ve değerlendirilmesidir.
Önsöz xi

Sayfa 13
xii
İçindekiler
1. Bölüm Ön Hazırlıklar
1
1.1 Programlama Dilleri Kavramlarını Çalışma Nedenleri ....................... 2
1.2 Programlama Etki Alanları ................................................................. ...................... 5
1.3 Dil Değerlendirme Kriterleri ................................................................ .................. 7
1.4 Dil Tasarımına Etkiler ................................................................. .......... 18
1.5 Dil Kategorileri ..................................................... ................................ 21
1.6 Dil Tasarımı Ödünleri ................................................................ ................................ 23
1.7 Uygulama Yöntemleri ................................................................. ................... 23
1.8 Programlama Ortamları ................................................................. ............ 31
Özet • Gözden Geçirme Soruları • Problem Seti ................................................. ... 31
Bölüm 2 Başlıca Programlama Dillerinin Evrimi
35
2.1 Zuse'nin Plankalkül'ü ................................................................ ................................38
2.2 Sözde kodlar ................................................................ ................................................ 39
2.3 IBM 704 ve Fortran ................................................................ ................................42
2.4 Fonksiyonel Programlama: LISP ................................................................ ......... 47
2.5 Gelişmişliğe Doğru İlk Adım: ALGOL 60 .................................. 52
2.6 İş Kayıtlarının Bilgisayarlaştırılması: COBOL ................................................. 58
2.7 Devre Paylaşımın Başlangıcı: TEMEL ................................................. 63
Röportaj: ALAN COOPER—Kullanıcı Tasarımı ve Dil Tasarımı ................. 66
2.8 Herkes İçin Her Şey: PL/I ................................................................ ............ 68
2.9 İki Erken Dinamik Dil: APL ve SNOBOL ................................. 71
2.10 Veri Soyutlamanın Başlangıcı: SIMULA 67 .................................. 72
2.11 Ortogonal Tasarım: ALGOL 68 ................................................ ........... 73
2.12 ALGOL'lerin Bazı Erken Torunları .................................................. 75

Sayfa 14
İçindekiler xiii
2.13 Mantığa Dayalı Programlama: Prolog ................................................................ .. 79
2.14 Tarihin En Büyük Tasarım Çabası: Ada ................................................................ ... 81
2.15 Nesneye Yönelik Programlama: Smalltalk ................................................ 85
2.16 Zorunlu ve Nesne Yönelimli Özellikleri Birleştirme: C++................ 88
2.17 Zorunlu Tabanlı Nesne Yönelimli Bir Dil: Java ................................. 91
2.18 Komut Dosyası Dilleri ................................................................ ................................ 95
2.19 Amiral Gemisi .NET Dili: C# ................................................ .......101
2.20 İşaretleme/Karma Dilleri Programlama ................................................. 104
Özet • Bibliyografik Notlar • İnceleme Soruları • Problem Seti •
Programlama Alıştırmaları ................................................................ ................................ 106
Bölüm 3 Sözdizimi ve Semantiği Tanımlama
113
3.1 Giriş ................................................................ ................................................ 114
3.2 Sözdizimi Tanımlamanın Genel Sorunu ................................................. 115
3.3 Sözdizimi Tanımlamanın Resmi Yöntemleri ................................................. 117
3.4 Nitelik Dilbilgileri ................................................................. ...................... 132
Tarih Notu ................................................................ ................................................... 133
3.5 Programların Anlamlarının Tanımlanması: Dinamik Semantik ................ 139
Tarih Notu ................................................................ ................................................ 154
Özet • Bibliyografik Notlar • Gözden Geçirme Soruları • Problem Seti ...................... 161
Bölüm 4 Sözcük ve Sözdizimi Analizi
167
4.1 Giriş ................................................................ ................................................168
4.2 Sözcük Analizi ................................................................. ................................ 169
4.3 Ayrıştırma Sorunu ................................................................ ...................... 177
4.4 Özyinelemeli-Descent Ayrıştırma ................................................................ ................................ 181
4.5 Aşağıdan Yukarıya Ayrıştırma .................................................. ................................ 190
Özet • Gözden Geçirme Soruları • Problem Seti • Programlama Alıştırmaları ..... 197
Bölüm 5 İsimler, Bağlar ve Kapsamlar
203
5.1 Giriş ................................................................ ................................ 204
5.2 İsimler ................................................................ ................................................ 205
Tarih Notu ................................................................ ...................................................205

Sayfa 15
xiv
İçindekiler
5.3 Değişkenler ................................................................ ................................................ 207
5.4 Bağlama Kavramı ................................................................. ................... 209
5.5 Kapsam ................................................................ ................................................ 218
5.6 Kapsam ve Ömür ................................................................ ................................ 229
5.7 Referans Ortamları ................................................................. .................230
5.8 Adlandırılmış Sabitler ................................................................. ................................ 232
Özet • Gözden Geçirme Soruları • Problem Seti • Programlama Alıştırmaları ..... 234
Bölüm 6 Veri Tipleri
243
6.1 Giriş ................................................................ ................................................244
6.2 İlkel Veri Tipleri ................................................................ ...................... 246
6.3 Karakter Dizisi Türleri ................................................................ ................... 250
Tarih Notu ................................................................ ................................................251
6.4 Kullanıcı Tanımlı Sıra Türleri ................................................ .................255
6.5 Dizi Türleri ................................................................. ................................................... 259
Tarih Notu ................................................................ ................................................260
Tarih Notu ................................................................ ................................................... 261
6.6 İlişkili Diziler ................................................................. ................................ 272
Röportaj: ROBERTO IERUSALIMSCHY—Lua ................................. 274
6.7 Kayıt Türleri ................................................................. ................................................ 276
6.8 Grup Türleri ................................................................. ................................................... 280
6.9 Liste Türleri ................................................................. ................................................... 281
6.10 Birlik Türleri ................................................................. ................................................ 284
6.11 İşaretçi ve Referans Türleri ................................................................ ............ 289
Tarih Notu ................................................................ ................................................... 293
6.12 Tip Kontrolü ................................................................. ................................302
6.13 Güçlü Yazma ................................................................. ................................303
6.14 Tip Eşdeğerliği ................................................................. .................................304
6.15 Teori ve Veri Tipleri ................................................................ .................... 308
Özet • Bibliyografik Notlar • İnceleme Soruları • Problem Seti •
Programlama Alıştırmaları ................................................................ ................................ 310

Sayfa 16
İçindekiler xv
Bölüm 7 İfadeler ve Atama İfadeleri
317
7.1 Giriş ................................................................ ................................................ 318
7.2 Aritmetik İfadeler ................................................................. ................. 318
7.3 Aşırı Yüklenmiş Operatörler ................................................................. .................... 328
7.4 Tip Dönüşümleri ................................................................. ................................ 329
Tarih Notu ................................................................ .................................................... 332
7.5 İlişkisel ve Boole İfadeleri ................................................................ 332
Tarih Notu ................................................................ .................................................... 333
7.6 Kısa Devre Değerlendirmesi ................................................................. ................. 335
7.7 Atama İfadeleri ................................................................. ................. 336
Tarih Notu ................................................................ ................................................... 340
7.8 Karma Mod Atama ................................................................ ................. 341
Özet • Gözden Geçirme Soruları • Problem Seti • Programlama Alıştırmaları ..... 341
Bölüm 8 İfade Düzeyinde Kontrol Yapıları
347
8.1 Giriş ................................................................ ................................................ 348
8.2 Seçim İfadeleri ................................................................. .................... 350
8.3 Yinelemeli İfadeler ................................................................. ...................... 362
8.4 Koşulsuz Dallanma ................................................................. ................. 375
Tarih Notu ................................................................ ................................................ 376
8.5 Korunan Komutlar ................................................................. ...................... 376
8.6 Sonuçlar ................................................................ ................................................ 379
Özet • Gözden Geçirme Soruları • Problem Seti • Programlama Alıştırmaları ..... 380
Bölüm 9 Alt Programlar
387
9.1 Giriş ................................................................ ................................................ 388
9.2 Alt Programların Temelleri ..................................................... ....... 388
9.3 Alt Programlar için Tasarım Konuları ................................................................ ........ 396
9.4 Yerel Referans Ortamları ................................................................ ..... 397
9.5 Parametre Geçiş Yöntemleri ................................................................. ............ 399
Tarih Notu ................................................................ ................................................ 407
Tarih Notu ................................................................ ................................................ 407

Sayfa 17
xvi
İçindekiler
9.6 Alt Program Olan Parametreler .................................................. .. 417
9.7 Alt Programları Dolaylı Olarak Çağırmak ................................................................ ....... 419
Tarih Notu ................................................................ ................................................... 419
9.8 Aşırı Yüklenmiş Alt Programlar ................................................................. ................... 421
9.9 Genel Alt Programlar ................................................................. .................... 422
9.10 Fonksiyonlar için Tasarım Konuları ................................................................ .................. 428
9.11 Kullanıcı Tanımlı Aşırı Yüklenmiş Operatörler .................................................. ... 430
9.12 Kapanışlar ................................................................ ................................................ 430
9.13 Eşyordamlar ................................................................ ................................................ 432
Özet • Gözden Geçirme Soruları • Problem Seti • Programlama Alıştırmaları ..... 435
Bölüm 10 Alt Programları Uygulamak
441
10.1 Çağrıların ve Geri Dönüşlerin Genel Anlamı ................................................. 442
10.2 “Basit” Alt Programların Uygulanması ................................................. 443
10.3 Yığın Dinamik Yerel Değişkenlerle Alt Programları Uygulamak ... 445
10.4 İç İçe Alt Programlar ..................................................... ...................... 454
10.5 Bloklar ..................................................... ................................................ 460
10.6 Dinamik Kapsamın Uygulanması .................................................. ...... 462
Özet • Gözden Geçirme Soruları • Problem Seti • Programlama Alıştırmaları ..... 466
Bölüm 11 Soyut Veri Tipleri ve Kapsülleme Yapıları
473
11.1 Soyutlama Kavramı ................................................................ ................ 474
11.2 Veri Soyutlamaya Giriş ................................................................ ..... 475
11.3 Soyut Veri Tipleri için Tasarım Konuları ................................................................ 478
11.4 Dil Örnekleri ................................................................. ...................... 479
Röportaj: BJARNE STROUSTRUP—C++: Doğuşu,
Her Yerde Bulunması ve Ortak Eleştirileri ................................................ 480
11.5 Parametreli Soyut Veri Tipleri ................................................................. .. 503
11.6 Kapsülleme Yapıları ................................................................. ................ 509
11.7 Kapsüllemeleri Adlandırma .................................................. ................. 513
Özet • Gözden Geçirme Soruları • Problem Seti • Programlama Alıştırmaları ..... 517

Sayfa 18
İçindekiler xvii
Bölüm 12 Nesne Yönelimli Programlama Desteği
523
12.1 Giriş ................................................................ ................................................ 524
12.2 Nesneye Yönelik Programlama ................................................................ ......... 525
12.3 Nesne Yönelimli Diller için Tasarım Sorunları ................................................. 529
12.4 Smalltalk'ta Nesneye Yönelik Programlama Desteği ................................. 534
Röportaj: BJARNE STROUSTRUP—Paradigmalar ve Daha İyisi Üzerine
Programlama ................................................................ ................................................ 536
12.5 C++'da Nesne Yönelimli Programlama Desteği ................................. 538
12.6 Objective-C'de Nesne Yönelimli Programlama Desteği ................ 549
12.7 Java'da Nesne Yönelimli Programlama Desteği ................................. 552
12.8 C#'da Nesne Yönelimli Programlama Desteği ................................. 556
12.9 Ada'da Nesne Yönelimli Programlama Desteği 95 ................................. 558
12.10 Ruby'de Nesne Yönelimli Programlama Desteği ................................ 563
12.11 Nesneye Yönelik Yapıların Uygulanması ................................................. 566
Özet • Gözden Geçirme Soruları • Problem Seti • Programlama Alıştırmaları .... 569
Bölüm 13 Eşzamanlılık
575
13.1 Giriş ................................................................ ................................................ 576
13.2 Alt Program Düzeyinde Eşzamanlılığa Giriş .................................. 581
13.3 Semaforlar ................................................................ ................................................ 586
13.4 Monitörler ..................................................... ...................................................... 591
13.5 Mesaj Geçişi ................................................................. ................................ 593
13.6 Eşzamanlılık için Ada Desteği ................................................. ......... 594
13.7 Java Konuları ................................................................. ................................ 603
13.8 C# Konuları ................................................................. ................................................ 613
13.9 İşlevsel Dillerde Eşzamanlılık ................................................. 618
13.10 İfade Düzeyinde Eşzamanlılık .................................................. ......... 621
Özet • Bibliyografik Notlar • İnceleme Soruları • Problem Seti •
Programlama Alıştırmaları ................................................................ ................................ 623

Sayfa 19
xviii
İçindekiler
Bölüm 14 İstisna İşleme ve Olay İşleme
629
14.1 İstisna İşleme Girişi ................................................................ 630
Tarih Notu ................................................................ ................................................ 634
14.2 Ada'da İstisna İşleme ................................................................ ................ 636
14.3 C++'da İstisna İşleme ................................................................ ................ 643
14.4 Java'da İstisna İşleme ................................................................ ................ 647
14.5 Olay Yönetimine Giriş ................................................................. ........ 655
14.6 Java ile Olay İşleme ................................................................ ................ 656
14.7 C#'da Olay İşleme ................................................................ ...................... 661
Özet • Bibliyografik Notlar • İnceleme Soruları • Problem Seti •
Programlama Alıştırmaları ................................................................ ................................ 664
Bölüm 15 Fonksiyonel Programlama Dilleri
671
15.1 Giriş ................................................................ ................................................ 672
15.2 Matematiksel Fonksiyonlar ................................................................. ................ 673
15.3 Fonksiyonel Programlama Dillerinin Temelleri .................... 676
15.4 İlk İşlevsel Programlama Dili: LISP ................................. 677
15.5 Şemaya Giriş ................................................................ ................ 681
15.6 Ortak LISP ................................................................. ................................ 699
15.7 ML ................................................................. ................................................ 701
15.8 Haskell ................................................................. ................................................ 707
15.9 F# ................................................................ ................................................................ 712
15.10 Öncelikli Olarak Fonksiyonel Programlama Desteği
Zorunlu Diller ................................................................ ...................... 715
15.11 İşlevsel ve Zorunlu Dillerin Karşılaştırılması ................................. 717
Özet • Bibliyografik Notlar • İnceleme Soruları • Problem Seti •
Programlama Alıştırmaları ................................................................ ................................ 720
Bölüm 16 Mantık Programlama Dilleri
727
16.1 Giriş ................................................................ ................................................ 728
16.2 Yüklem Analizine Kısa Bir Giriş ................................................. 728
16.3 Yüklem Analizi ve Teoremleri Kanıtlama .................................................. 732

Sayfa 20
İçindekiler xix
16.4 Mantıksal Programlamaya Genel Bir Bakış ................................................................ .. 734
16.5 Prolog'un Kökenleri ................................................................. ...................... 736
16.6 Prolog'un Temel Öğeleri ................................................................ ........... 736
16.7 Prolog Eksiklikleri ................................................................. .................... 751
16.8 Mantık Programlama Uygulamaları ................................................................. 757
Özet • Bibliyografik Notlar • İnceleme Soruları • Problem Seti •
Programlama Alıştırmaları ................................................................ ................................ 758
Bibliyografya ................................................................ ................................ 763
Dizin ................................................................ ................................................ 773

Sayfa 21
Bu sayfa bilerek boş bırakılmıştır

Sayfa 22
1
1.1 Programlama Dillerinin Kavramlarını Çalışmak İçin Nedenler
1.2 Programlama Etki Alanları
1.3 Dil Değerlendirme Kriterleri
1.4 Dil Tasarımına Etkiler
1.5 Dil Kategorileri
1.6 Dil Tasarımı Ödünleri
1.7 Uygulama Yöntemleri
1.8 Programlama Ortamları
1
ön elemeler

Sayfa 23
2
1. Bölüm Ön Hazırlıklar
B biz gerekir, programlama dillerinin kavramlarını konuşmaya başlamak DONANIMI
birkaç ön bilgi düşünün. İlk olarak, bilgisayarın neden bazı nedenlerini açıklıyoruz.
bilim öğrencileri ve profesyonel yazılım geliştiriciler genel çalışmalıdır
dil tasarımı ve değerlendirme kavramları. Bu tartışma özellikle değerlidir.
bir veya iki programlama bilgisinin işe yaradığına inananlar için mümkün
diller bilgisayar bilimcileri için yeterlidir. Ardından, ana konuyu kısaca açıklıyoruz.
programlama alanları Daha sonra, kitap dil ​​yapılarını değerlendirdiği ve
özellikleri, bu tür yargılara temel teşkil edebilecek bir kriterler listesi sunuyoruz.
Ardından, dil tasarımı üzerindeki iki ana etkiyi tartışıyoruz: makine mimarisi
ve program tasarım metodolojileri. Bundan sonra, çeşitli kategorileri tanıtıyoruz.
programlama dillerinden. Daha sonra, birkaç önemli değiş tokuştan bahsedeceğiz.
dil tasarımı sırasında dikkate alınmalıdır.
Bu kitap aynı zamanda programlama dillerinin uygulanmasıyla ilgili olduğundan,
bu bölüm, uygulamaya yönelik en yaygın genel yaklaşımlara genel bir bakış içerir.
mental aktivite. Son olarak, birkaç programlama ortamı örneğini kısaca açıklıyoruz.
ve yazılım üretimi üzerindeki etkilerini tartışın.
1.1 Programlama Dillerinin Kavramlarını Çalışmak İçin Nedenler
Öğrencilerin mesleki eğitimden nasıl yararlanacaklarını merak etmeleri doğaldır.
dilbilgisi kavramları. Sonuçta, bilgisayar bilimindeki diğer birçok konu
ciddi bir araştırmaya değer. Aşağıdakiler, bir zorunluluk olduğuna inandığımız şeydir.
Programlama dilleri kavramlarını incelemenin potansiyel faydalarının listesi:
Fikirleri ifade etme kapasitesinin artması. derinliğinin olduğuna yaygın olarak inanılmaktadır.
insanların düşünebileceği şey, arazinin ifade gücünden etkilenir.
düşüncelerini ilettikleri bir göstergedir. Sadece zayıf olanlar
doğal dilin anlaşılması, dillerinin karmaşıklığıyla sınırlıdır.
düşünceler, özellikle soyutlama derinliği. Başka bir deyişle, zor
insanların sözlü veya sözlü olarak tanımlayamadıkları yapıları kavramsallaştırmaları için
yazı.
Yazılım geliştirme sürecindeki programcılar da benzer şekilde
gergin. Yazılım geliştirdikleri dil,
kontrol yapıları, veri yapıları ve yapabilecekleri soyutlama türleri
kullanmak; bu nedenle, oluşturabilecekleri algoritma biçimleri de aynı şekilde sınırlıdır.
Daha geniş çeşitlilikteki programlama dili özelliklerinin farkındalığı,
yazılım geliştirmede bu tür sınırlamalar. Programcılar şunları artırabilir:
yeni öğrenerek yazılım geliştirme düşünce süreçlerinin bir dizi
dil yapıları.
Diğer dillerin yeteneklerini öğrenmenin,
bunlardan yoksun bir dili kullanmak zorunda kalan bir programcıya yardım etmeyin.
yetenekler. Bununla birlikte, bu argüman geçerli değildir, çünkü çoğu zaman, lan-
guage yapıları, desteklemeyen diğer dillerde simüle edilebilir.
bu yapılar doğrudan Örneğin, öğrenmiş bir C programcısı
Perl'deki ilişkisel dizilerin yapısı ve kullanımları (Wall ve diğerleri, 2000)
o dilde ilişkisel dizileri simüle eden tasarım yapıları. Diğer

Sayfa 24
1.1 Programlama Dilleri Kavramlarını Çalışma Nedenleri 3
kelimeler, programlama dili kavramlarının incelenmesi bir takdir oluşturur
değerli dil özellikleri için programcıları yapılandırır ve teşvik eder
kullandıkları dil doğrudan desteklemese bile bunları kullanmak
bu tür özellikleri ve yapıları taşır.
Uygun dilleri seçmek için iyileştirilmiş arka plan. Birçok profesyonel
programcılar bilgisayar bilimlerinde çok az resmi eğitim almış; yerine,
programlama becerilerini bağımsız olarak veya in-
ev eğitim programları. Bu tür eğitim programları genellikle öğretimi aşağıdakilerle sınırlandırır:
mevcut projeleriyle doğrudan ilgili bir veya iki dil
organizasyon. Diğer birçok programcı resmi eğitim yıllarını aldı
evvel. O zaman öğrendikleri diller artık kullanılmamakta ve birçok özellik
şimdi programlama dillerinde mevcuttu, o zamanlar yaygın olarak bilinmiyordu.
Sonuç olarak, birçok programcıya bir dil seçeneği verildiğinde
yeni bir projede, en aşina oldukları dili kullanın, öyle olsa bile
eldeki proje için yetersiz. Bu programcılar aşina olsaydı
daha geniş bir dil ve dil yapısı yelpazesi, daha iyi
sorunu en iyi şekilde ele alan özelliklere sahip dili seçmek için.
Bir dilin bazı özellikleri genellikle başka bir dilde simüle edilebilir.
dilim. Ancak, tasarımı değiştirilmiş bir özelliğin kullanılması tercih edilir.
bu özelliğin bir simülasyonunu kullanmak yerine bir dile entegre
genellikle daha az zarif, daha hantal ve daha az güvenlidir.
Artan yeni diller öğrenme yeteneği. Bilgisayar programlama hala bir
son derece genç disiplin ve tasarım metodolojileri, yazılım geliştirme
araçlar ve programlama dilleri hala sürekli bir evrim halindedir.
tion. Bu, yazılım geliştirmeyi heyecan verici bir meslek haline getirir, ancak aynı zamanda
sürekli öğrenmenin gerekli olduğu anlamına gelir. Yeni bir öğrenme süreci
programlama dili, özellikle birileri için uzun ve zor olabilir
sadece bir veya iki dilde rahat olan ve hiç sınava girmemiş olan
genel olarak programlama dili kavramları. Bir kez kapsamlı bir anlayış
dillerin temel kavramları edinilirse, çok daha kolay hale gelir.
bu kavramların dil tasarımına nasıl dahil edildiğini görmek için
öğreniliyor. Örneğin, kavramlarını anlayan programcılar
nesne yönelimli programlama, Java'yı öğrenmek için çok daha kolay bir zamana sahip olacak
(Arnold ve ark., 2006) bu kavramları hiç kullanmayanlara göre daha fazladır.
Aynı fenomen doğal dillerde de görülür. sen daha iyi
ana dilinizin gramerini bilirseniz, bir saniye öğrenmek o kadar kolay olur.
ond dil. Ayrıca, ikinci bir dil öğrenmenin faydaları vardır.
size ana diliniz hakkında daha fazla şey öğretmek.
TIOBE Programlama Topluluğu bir dizin yayınlar (http://www
.tiobe.com/tiobe_index/index.htm) bir göstergesidir.
programlama dillerinin göreceli popülaritesi. Örneğin, göre
dizin, Java, C ve C++ kullanımda olan en popüler üç dildi
Ağustos 2011'de. 1 Bununla birlikte, düzinelerce başka dil yaygın olarak kullanıldı.
1. Bu dizinin, programlama dillerinin popülaritesinin yalnızca bir ölçüsü olduğuna dikkat edin ve
doğruluğu evrensel olarak kabul edilmez.

Sayfa 25
4
1. Bölüm Ön Hazırlıklar
zaman. Endeks verileri ayrıca pro-
gramer dilleri sürekli değişiyor. Kullanılan dil sayısı
ve istatistiklerin dinamik doğası, her yazılım geliştiricinin
farklı dilleri öğrenmeye hazır olmalıdır.
Son olarak, pratik yapan programcıların kelime dağarcığını bilmeleri önemlidir.
ve programlama dillerinin temel kavramlarını okuyabilmeleri ve
programlama dili açıklamalarını ve değerlendirmelerini anlamanın yanı sıra
diller ve derleyiciler için tanıtım literatürü. kaynaklar bunlar
Bir dil seçmek ve öğrenmek için gerekli bilgiler.
Uygulamanın öneminin daha iyi anlaşılması. Kon-
programlama dillerinin kavramlarına dokunmak hem ilginç hem de gerekli
Bu kavramları etkileyen uygulama konuları hakkında. Bazı durumlarda, bir
uygulama konularının anlaşılması, nedenin anlaşılmasına yol açar.
diller oldukları gibi tasarlanmıştır. Buna karşılık, bu bilgi yol açar
kullanılmak üzere tasarlandığından, bir dili daha akıllıca kullanma yeteneği.
Aşağıdaki seçenekleri anlayarak daha iyi programcılar olabiliriz.
programlama dili yapıları ve bu seçimlerin sonuçları.
Belirli türdeki program hataları yalnızca bir uzman tarafından bulunabilir ve düzeltilebilir.
Bazı ilgili uygulama ayrıntılarını bilen gramer. Başka bir ben-
uygulama sorunlarını anlamanın yararı, görselleştirmemize izin vermesidir.
bir bilgisayarın çeşitli dil yapılarını nasıl yürüttüğü. Bazı durumlarda, bazı
uygulama konularına ilişkin bilgi, göreceli verimlilik hakkında ipuçları sağlar.
bir program için seçilebilecek alternatif yapıların doğruluğu. İçin
örneğin, uygulamanın karmaşıklığı hakkında çok az şey bilen programcılar
alt program çağrılarının belirtilmesi, genellikle küçük bir alt programın
Sıklıkla adlandırılan bu, oldukça verimsiz bir tasarım seçimi olabilir.
Çünkü bu kitap uygulama konularının sadece birkaçına değinmektedir.
tion, önceki iki paragraf da çalışmak için gerekçe olarak hizmet eder.
derleyici tasarımı.
Bilinen dillerin daha iyi kullanılması. Birçok çağdaş program-
ming dilleri büyük ve karmaşıktır. Buna göre, yaygın olmayan
bir dilin tüm özelliklerini bilen ve kullanan bir programcı
o kullanır. Programlama dillerinin kavramlarını inceleyerek, pro-
gramerler, daha önce bilinmeyen ve kullanılmayan kısımlar hakkında bilgi edinebilir.
zaten kullandıkları ve bu özellikleri kullanmaya başladıkları diller.
• Bilgisayarın genel gelişimi. Son olarak, küresel bir bilgisayar görüşü vardır.
Bu, programlama dili kavramlarının çalışılmasını haklı gösterebilir. Rağmen
belirli bir programlama dilinin nedenini belirlemek genellikle mümkündür
popüler hale geldi, çoğu kişi, en azından geçmişe bakıldığında, en popüler
lar diller her zaman mevcut en iyi diller değildir. Bazı durumlarda, olabilir
bir dilin en azından kısmen yaygın olarak kullanılmaya başlandığı sonucuna varmıştır, çünkü
dil seçebilecek konumda olanlar yeterince aşina değildi
programlama dili kavramları.
Örneğin, birçok insan ALGOL olsaydı daha iyi olacağına inanıyor.
60 (Backus ve diğerleri, 1963) Fortran'ın (Metcalf ve diğerleri, 2004) yerini almıştı.

Sayfa 26
1.2 Programlama Etki Alanları 5
1960'ların başında, çünkü daha zarifti ve çok daha iyi kontrol durumuna sahipti-
diğer nedenlerin yanı sıra. Olmaması, kısmen programdan kaynaklanıyor.
o zamanın mers ve yazılım geliştirme yöneticileri, çoğu yaptı
ALGOL 60'ın kavramsal tasarımını net olarak anlayamadılar.
açıklamanın okunması zor (ki öyleydi) ve anlaşılması daha da zordu.
durmak. Blok yapısının, özyinelemenin faydalarını takdir etmediler,
ve iyi yapılandırılmış kontrol ifadeleri, bu nedenle faydalarını göremediler.
Fortran üzerinden ALGOL 60.
Tabii ki, diğer birçok faktör kabul edilmemesine katkıda bulundu.
ALGOL 60, Bölüm 2'de göreceğimiz gibi, bilgisayar
Kullanıcılar, genellikle, önemli bir rol oynayan dilin yararlarından habersizdiler.
güzel rol.
Genel olarak, dil seçenler iyi bilgilendirilmiş olsaydı, belki
daha iyi diller sonunda daha fakir olanları sıkıştıracaktır.
1.2 Programlama Etki Alanları
Bilgisayarlar, kontrolden, sayısız farklı alana uygulandı.
cep telefonlarında video oyunları sağlamak için nükleer santraller. çünkü
bilgisayar kullanımındaki bu büyük çeşitlilik, çok farklı programlama dilleri
hedefler geliştirilmiştir. Bu bölümde kısaca bazı alanlardan bahsedeceğiz.
bilgisayar uygulamaları ve bunlarla ilişkili diller.
1.2.1 Bilimsel Uygulamalar
1940'ların sonlarında ve 1950'lerin başlarında ortaya çıkan ilk dijital bilgisayarlar,
icat edilmiş ve bilimsel uygulamalar için kullanılmıştır. Tipik olarak, bilimsel uygulama-
o zamanın katyonları nispeten basit veri yapıları kullandı, ancak büyük
kayan noktalı aritmetik hesaplamaların sayısı. En yaygın veriler
yapılar diziler ve matrislerdi; en yaygın kontrol yapıları
döngüleri ve seçimleri sayma. Erken yüksek seviyeli programlama dilleri
Bilimsel uygulamalar için icat edilenler bu ihtiyaçları karşılamak için tasarlandı.
Rakipleri montaj diliydi, bu nedenle verimlilik birincil endişeydi.
Bilimsel uygulamalar için ilk dil Fortran'dı. ALGOL 60 ve çoğu
soyundan gelenlerin de bu alanda kullanılması amaçlanmıştır.
ilgili alanlarda da kullanılmak üzere tasarlanmıştır. Bazı bilimsel uygulamalar için
verimliliğin birincil endişe olduğu durumlarda, örneğin, geçmişte yaygın olanlar gibi
1950'ler ve 1960'lar, sonraki hiçbir dil Fortran'dan önemli ölçüde daha iyi değildir,
bu da Fortran'ın neden hala kullanıldığını açıklıyor.
1.2.2 İş Uygulamaları
Bilgisayarların iş uygulamaları için kullanımı 1950'lerde başladı. Özel
özel dillerle birlikte bilgisayarlar bu amaç için geliştirildi. bu
iş için ilk başarılı üst düzey dil COBOL'du (ISO/IEC, 2002),

Sayfa 27
6
1. Bölüm Ön Hazırlıklar
ilk versiyonu 1960'da ortaya çıktı. Hala en yaygın olanıdır.
Bu uygulamalar için kullanılan dil. İş dilleri aşağıdakilerle karakterize edilir:
ayrıntılı raporlar, kesin tanımlama ve saklama yolları üretmek için tesisler
ondalık sayılar ve karakter verileri ve ondalık belirtme yeteneği
Aritmetik işlemler.
İş uygulama dillerinde çok az gelişme olmuştur.
COBOL'un gelişimi ve evriminin yanında. Bu nedenle, bu kitap şunları içerir:
COBOL'deki yapılarla ilgili yalnızca sınırlı tartışmalar.
1.2.3 Yapay Zeka
Yapay zeka (AI), bilgisayar uygulamaları karakterlerinin geniş bir alanıdır.
sayısal hesaplamalardan ziyade sembolik hesaplamalar kullanılarak tertip edilir. Simgesel
hesaplama, sayılardan ziyade isimlerden oluşan sembollerin,
manipüle edilmektedir. Ayrıca, sembolik hesaplama ile daha uygun bir şekilde yapılır.
diziler yerine bağlantılı veri listeleri. Bu tür programlama bazen
diğer programlama etki alanlarından daha fazla esneklik gerektirir. örneğin,
bazı AI uygulamaları sırasında kod segmentleri oluşturma ve yürütme yeteneği
yürütme uygundur.
AI uygulamaları için geliştirilen ilk yaygın olarak kullanılan programlama dili
ortaya çıkan işlevsel dil LISP idi (McCarthy ve diğerleri, 1965).
1959'da. 1990'dan önce geliştirilen çoğu AI uygulaması LISP'de yazılmıştır.
veya yakın akrabalarından biri. Ancak 1970'lerin başında, bir alternatif
bu uygulamalardan bazılarına yaklaşım ortaya çıktı - kullanarak mantıksal programlama
Prolog (Clocksin ve Mellish, 2003) dili. Daha yakın zamanlarda, bazı
AI uygulamaları, C. Scheme gibi sistem dillerinde yazılmıştır.
(Dybvig, 2003), LISP'in bir lehçesi ve Prolog 15. Bölümde tanıtılmaktadır.
ve sırasıyla 16.
1.2.4 Sistem Programlama
Bir bilgisayar sisteminin işletim sistemi ve programlama destek araçları
tem topluca sistem yazılımı olarak bilinir . Sistem yazılımı kullanılır
neredeyse süreklidir ve bu nedenle verimli olmalıdır. Ayrıca, düşük olmalıdır-
yazılım arayüzlerinin harici cihazlara yazılmasına izin veren seviye özellikleri.
1960'larda ve 1970'lerde IBM gibi bazı bilgisayar üreticileri,
Digital ve Burroughs (şimdi UNISYS), makine odaklı özel geliştirdi
makinelerinde sistem yazılımı için üst düzey diller. IBM ana için
çerçeve bilgisayarları, dil PL/S, PL/I'nin bir lehçesiydi; Dijital için,
BLISS, Assembly dilinin hemen üzerinde bir seviyede bir dil; Burroughs için,
Genişletilmiş ALGOL oldu. Ancak, çoğu sistem yazılımı artık daha fazla
C ve C++ gibi genel programlama dilleri.
UNIX işletim sistemi neredeyse tamamen C ile yazılmıştır (ISO, 1999),
bu, farklı makinelere taşınmasını veya taşınmasını nispeten kolaylaştırdı. Bazı
C'nin özelliklerinden dolayı, sistem programlaması için iyi bir seçimdir.
Düşük seviyelidir, yürütme açısından verimlidir ve kullanıcıya çok fazla yük getirmez.

Sayfa 28
1.3 Dil Değerlendirme Kriterleri 7
güvenlik kısıtlamaları. Sistem programcıları genellikle mükemmel programcılardır
bu tür kısıtlamalara ihtiyaçları olmadığına inananlar. Bazı sistem dışı program-
Ancak, C'yi büyük, önemli yazılımlarda kullanmak için çok tehlikeli buluyorlar.
sistemler.
1.2.5 Web Yazılımı
World Wide Web, eklektik bir dil koleksiyonu tarafından desteklenir,
programlama olmayan HTML gibi biçimlendirme dillerinden
Java gibi genel amaçlı programlama dillerine. Çünkü
Dinamik Web içeriğine olan yaygın ihtiyaçtan dolayı, bazı hesaplama yetenekleri
genellikle içerik sunumu teknolojisine dahil edilir. Bu işlevsellik
programlama kodunu bir HTML belgesine gömerek sağlanabilir.
Bu tür kodlar genellikle JavaScript veya
PHP. Genişletilmiş bazı biçimlendirme benzeri diller de vardır.
bölümünde tartışılan belge işlemeyi kontrol eden yapıları içerir.
Bölüm 1.5 ve Bölüm 2'de.
1.3 Dil Değerlendirme Kriterleri
Daha önce belirtildiği gibi, bu kitabın amacı, aşağıdakileri dikkatlice incelemektir:
programlama dilinin çeşitli yapıları ve yetenekleriyle ilgili temel kavramlar
göstergeler. Aynı zamanda, bu özellikleri, bunların çevreye olan etkilerine odaklanarak değerlendireceğiz.
bakım dahil olmak üzere yazılım geliştirme süreci. Bunu yapmak için bir sete ihtiyacımız var.
değerlendirme kriterlerindendir. Böyle bir kriter listesi mutlaka tartışmalıdır, çünkü
iki bilgisayar bilimcinin bile bazılarının değeri üzerinde anlaşmasını sağlamak zordur.
diğerlerine göre verilen dil özelliği. Bu farklılıklara rağmen,
çoğu, aşağıdaki alt bölümlerde tartışılan kriterlerin
önemli.
En önemli dört özellikten üçünü etkileyen özelliklerden bazıları
Bu kriterlerin bir kısmı Tablo 1.1'de gösterilmektedir ve kriterlerin kendileri
aşağıdaki bölümlerde tartışılmaktadır. 2 Yalnızca en önemli
tant özellikleri tabloda yer almakta ve tartışmayı yansıtmaktadır.
aşağıdaki alt bölümler. Biri muhtemelen bunu yapabilirdi, eğer biri
Daha az önemli özellikler olarak kabul edildiğinde, neredeyse tüm masa pozisyonları
"mermiler" içerir.
Bu özelliklerden bazılarının geniş ve biraz belirsiz olduğuna dikkat edin.
yazılabilirlik gibi, diğerleri ise belirli dil yapılarıdır, örneğin
istisna işleme. Ayrıca, tartışma ima ediyor gibi görünse de,
kriterlerin eşit öneme sahip olduğunu, ima amaçlı olmadığını ve
durumun böyle olmadığı açık.
2. Dördüncü birincil kriter maliyettir ve sadece maliyet olduğu için tabloda yer almaz.
diğer kriterler ve onları etkileyen özelliklerle biraz ilişkilidir.

Sayfa 29
8
1. Bölüm Ön Hazırlıklar
1.3.1 Okunabilirlik
Bir programlama dilini değerlendirmek için en önemli kriterlerden biri,
programların kolaylıkla okunup anlaşılabilmesini sağlar. 1970 öncesi yazılım
Geliştirme, büyük ölçüde kod yazmak açısından düşünülmüştü. Birincil
programlama dillerinin olumlu özelliği verimlilikti. Dilim
yapılar, bilgisayar bakış açısına göre daha fazla tasarlandı.
bilgisayar kullanıcıları arasında. 1970'lerde ise yazılım yaşam döngüsü kavramı
(Booch, 1987) geliştirildi; kodlama çok daha küçük bir role indirgendi ve
bakım, özellikle bakım açısından, döngünün önemli bir parçası olarak kabul edildi.
maliyeti. Çünkü bakım kolaylığı büyük ölçüde okuma ile belirlenir.
programların yeteneği, okunabilirlik kalitesinin önemli bir ölçüsü haline geldi.
programlar ve programlama dilleri. Bu önemli bir dönüm noktasıydı
programlama dillerinin evrimi. Farklı bir geçit vardı
insan yönelimine odaklanmak için makine yönelimine odaklanın.
Okunabilirlik, problem alanı bağlamında düşünülmelidir. İçin
örneğin, bir hesaplamayı açıklayan bir program olmayan bir dilde yazılmışsa,
bu tür bir kullanım için tasarlanmışsa, program doğal olmayan ve dolambaçlı olabilir,
okuması alışılmadık derecede zor.
Aşağıdaki alt bölümler, aşağıdakilere katkıda bulunan özellikleri açıklar:
Bir programlama dilinin okunabilirliği.
1.3.1.1 Genel Basitlik
Bir programlama dilinin genel sadeliği, okunabilirliğini güçlü bir şekilde etkiler.
ıt. Çok sayıda temel yapıya sahip bir dili öğrenmek daha zordur
daha küçük bir sayı ile birden. Büyük bir dil kullanması gereken programcılar
genellikle dilin bir alt kümesini öğrenir ve diğer özelliklerini görmezden gelir. Bu öğrenme
kalıp bazen çok sayıda dil yapısını mazur göstermek için kullanılır,
Tablo 1.1 Dil değerlendirme kriterleri ve bunları etkileyen özellikler
KRİTERLER
karakteristik
OKUNABİLİRLİK
YAZILABİLİRLİK
GÜVENİLİRLİK
Basitlik
ortogonallik
Veri tipleri
sözdizimi tasarımı
Soyutlama için destek
dışavurumculuk
Tip kontrolü
İstisna işleme
Kısıtlı takma ad

Sayfa 30
1.3 Dil Değerlendirme Kriterleri 9
ama bu argüman geçerli değil. Okunabilirlik sorunları, pro-
gram'ın yazarı, o alt kümeden farklı bir alt küme öğrenmiştir.
okuyucu tanıdıktır.
Bir programlama dilinin ikinci karmaşık özelliği, özelliktir.
çokluk - yani, belirli bir şeyi başarmak için birden fazla yola sahip olmak
operasyon. Örneğin, Java'da bir kullanıcı basit bir tamsayı değişkenini artırabilir.
dört farklı şekilde:
say = say + 1
sayı += 1
say++
++say
Son iki ifade birbirinden biraz farklı anlamlara sahip olsa da
diğer ve diğerlerinden bazı bağlamlarda, hepsi aynı anlama sahiptir.
tek başına ifadeler olarak kullanıldığında. Bu varyasyonlar tartışılır
Bölüm 7.
Üçüncü bir potansiyel problem, tek bir operatörün aşırı yüklenmesidir.
ator sembolü birden fazla anlama sahiptir. Bu genellikle yararlı olsa da,
kullanıcıların kendi aşırı yüklemelerini oluşturmalarına izin verilirse okunabilirliğin azalmasına yol açar
ve bunu mantıklı bir şekilde yapmayın. Örneğin, aşırı yük +
hem tamsayı hem de kayan nokta toplaması için kullanmak için. Aslında bu aşırı yükleme
operatör sayısını azaltarak dili basitleştirir. Ancak, varsayalım
programcı tanımlı + tek boyutlu dizi işlenenleri arasında kullanılır
her iki dizinin tüm öğelerinin toplamı anlamına gelir. Çünkü genel anlamı
vektör toplama bundan oldukça farklıdır, programı daha
hem yazar hem de programın okuyucuları için kafa karıştırıcı. Daha da aşırı
program karışıklığına örnek, iki vektör arasında + tanımlayan bir kullanıcı olabilir
işlenenler, ilgili ilk öğeleri arasındaki farkı ifade eder. Opera-
tor aşırı yüklemesi Bölüm 7'de daha ayrıntılı olarak tartışılmaktadır.
Dillerdeki sadelik elbette çok ileri götürülebilir. Örneğin,
Çoğu montaj dili ifadesinin biçimi ve anlamı, aşağıdakilerin modelleridir:
basitlik, ifadelerde yer alan ifadeleri göz önünde bulundurduğunuzda görebileceğiniz gibi
sonraki bölüm. Ancak bu çok basitlik, montaj dili programlarını
daha az okunabilir. Daha karmaşık kontrol ifadelerinden yoksun oldukları için, program
yapı daha az belirgindir; çünkü ifadeler basit, çok daha fazlası
yüksek seviyeli bir dilde eşdeğer programlardan daha gereklidir. bunlar aynı
argümanlar, yetersiz olan yüksek seviyeli dillerin daha az uç durumu için geçerlidir.
kontrol ve veri yapılandırma yapılarını eşitler.
1.3.1.2 Dikeylik
Bir programlama dilinde ortogonallik , nispeten küçük bir dizi
ilkel yapılar nispeten az sayıda yolla birleştirilebilir.
dilin kontrol ve veri yapılarını oluşturur. Ayrıca, her poz-
İlkellerin olası kombinasyonu yasal ve anlamlıdır. Örneğin, düşünün

Sayfa 31
10
1. Bölüm Ön Hazırlıklar
veri tipleri. Bir dilin dört ilkel veri türü olduğunu varsayalım (tamsayı, kayan nokta,
double ve karakter) ve iki tip operatör (dizi ve işaretçi). eğer ikisi
tür operatörleri kendilerine ve dört ilkel veri türüne uygulanabilir,
çok sayıda veri yapısı tanımlanabilir.
Ortogonal bir dil özelliğinin anlamı, dilden bağımsızdır.
bir programdaki görünümünün bağlamı. ( ortogonal kelimesi şuradan gelir:
birbirinden bağımsız olan ortogonal vektörlerin matematiksel kavramı
diğer.) Ortogonallik, ilkeller arasındaki ilişkilerin simetrisinden kaynaklanır.
tifler. Ortogonallik eksikliği, dil kurallarında istisnalara yol açar.
Örneğin, işaretçileri destekleyen bir programlama dilinde,
dilde tanımlanmış herhangi bir özel tipe işaret edecek bir işaretçi tanımlamak mümkündür.
Bununla birlikte, işaretçilerin dizileri işaret etmesine izin verilmezse, potansiyel olarak birçok yararlı
kullanıcı tanımlı veri yapıları tanımlanamaz.
Ortogonalliğin bir tasarım konsepti olarak kullanımını karşılaştırarak gösterebiliriz.
IBM ana bilgisayar bilgisayarlarının montaj dillerinin bir yönü
ve VAX serisi mini bilgisayarlar. Tek bir basit durumu ele alıyoruz:
bellekte veya kayıtlarda bulunan iki adet 32 ​​bit tamsayı değeri ekleyerek ve
iki değerden birinin toplamı ile değiştirilmesi. IBM ana bilgisayarlarında iki
formları olan bu amaca yönelik talimatlar
A Reg1, memory_cell
AR Reg1, Reg2
burada Reg1 ve Reg2 kayıtları temsil eder. Bunların semantiği
Reg1 ← içerik(Reg1) + içerik(memory_cell)
Reg1 ← içerik(Reg1) + içerik(Reg2)
32 bit tamsayı değerleri için VAX ekleme talimatı
ADDL işleneni_1, işlenen_2
kimin semantiği
işlenen_2 ← içerik(işlenen_1) + içerik(işlenen_2)
Bu durumda, işlenen bir kayıt veya bir bellek hücresi olabilir.
VAX komut tasarımı ortogonaldir, çünkü tek bir komut
işlenenler olarak kayıtları veya bellek hücrelerini kullanın. iki yol var
olası tüm yollarla birleştirilebilecek işlenenleri belirtin. IBM tasarımı
ortogonal değildir. Dört işlenen kombinasyon olasılığından sadece ikisi
yasaldır ve ikisi farklı talimatlar gerektirir, A ve AR . IBM tasarımı
daha kısıtlıdır ve bu nedenle daha az yazılabilirdir. Örneğin, ekleyemezsiniz
iki değer ve toplamı bir bellek konumunda saklayın. Ayrıca, IBM'in
kısıtlamalar ve ek özellikler nedeniyle tasarımın öğrenilmesi daha zordur.
talimat.

Sayfa 32
1.3 Dil Değerlendirme Kriterleri 11
Ortogonallik basitlikle yakından ilişkilidir:
Bir dilin tasarımı, dil kurallarının gerektirdiği istisnalar o kadar az olur. Daha az
istisnalar, tasarımda daha yüksek derecede düzenlilik anlamına gelir, bu da
öğrenmesi, okuması ve anlaması daha kolay bir dil. Bir işaret öğrenmiş olan herkes
İngilizce dilinin önemli bir kısmı, İngilizceyi öğrenmenin zorluğuna tanıklık edebilir.
birçok kural istisnası (örneğin, i'den önce e hariç, c 'den sonra ).
Yüksek seviyeli bir dilde ortogonallik eksikliğinin örnekleri olarak, düşünün
C'de aşağıdaki kurallar ve istisnalar vardır. C'nin iki tür yapısı olmasına rağmen
Tured veri türleri, diziler ve kayıtlar ( struct s), kayıtlar şuradan döndürülebilir:
işlevler ancak diziler yapamaz. Bir yapının üyesi herhangi bir veri türü olabilir
boşluk veya aynı türden bir yapı hariç . Bir dizi elemanı herhangi bir veri olabilir
void veya bir işlev dışında yazın . Parametreler, değere göre iletilir, aksi takdirde
dizilerdir, bu durumda aslında referans yoluyla iletilirler (çünkü
C programında bir dizi adının alt simge olmadan görünümü yorumlanır
dizinin ilk öğesinin adresi olmak için).
Bağlam bağımlılığına bir örnek olarak, C ifadesini düşünün.
bir + b
Bu ifade genellikle a ve b değerlerinin getirilip eklendiği anlamına gelir.
bir arada. Bununla birlikte, a bir işaretçi olursa, b'nin değerini etkiler . İçin
örneğin, a dört baytlık bir kayan noktalı değeri gösteriyorsa, b'nin değeri
ölçekli olarak gereken, bu durumda bu ilave edilir daha önce 4 ile çarpılarak bir . Öyleyse,
a tipi , b değerinin işlenmesini etkiler . b'nin bağlamı etkiler
anlamı.
Çok fazla ortogonallik de sorunlara neden olabilir. belki de en
ortogonal programlama dili ALGOL 68'dir (van Wijngaarden et al.,
1969). ALGOL 68'deki her dil yapısının bir türü vardır ve hiçbir
bu türler için kısıtlamalar. Ek olarak, çoğu yapı değerler üretir. Bu
kombinasyonel özgürlük, son derece karmaşık yapılara izin verir. Örneğin, bir
koşullu, bildirimlerle birlikte bir atamanın sol tarafı olarak görünebilir
ve sonuç bir adres olduğu sürece diğer çeşitli ifadeler. Bu aşırı
ortogonallik formu gereksiz karmaşıklığa yol açar. Ayrıca, çünkü
diller çok sayıda ilkel, yüksek derecede diklik gerektirir
kombinasyonların patlamasıyla sonuçlanır. Yani, kombinasyonlar basit olsa bile,
onların saf sayıları karmaşıklığa yol açar.
Bu nedenle, bir dilde sadelik, en azından kısmen bir karmaşıklığın sonucudur.
nispeten az sayıda ilkel yapının binasyonu ve sınırlı bir kullanım
ortogonallik kavramı.
Bazıları, işlevsel dillerin iyi bir sim-
çokluk ve ortogonallik. LISP gibi işlevsel bir dil, içinde
hesaplamalar öncelikle verilen parametrelere fonksiyonlar uygulanarak yapılır.
Buna karşılık, C, C++ ve Java gibi zorunlu dillerde hesaplamalar
genellikle değişkenler ve atama ifadeleri ile belirtilir. fonksiyonel
diller potansiyel olarak en büyük genel sadeliği sunar, çünkü
her şeyi tek bir yapıyla, işlev çağrısıyla gerçekleştirin.

Sayfa 33
12
1. Bölüm Ön Hazırlıklar
basitçe diğer işlev çağrılarıyla birleştirilir. Bu basit zarafet nedeni
neden bazı dil araştırmacıları işlevsel dillere ilgi duyuyor?
C++ gibi karmaşık işlevsel olmayan dillere birincil alternatif. Diğer
verimlilik gibi faktörler, ancak, işlevsel dillerin
daha yaygın olarak kullanılmaya başlanmıştır.
1.3.1.3 Veri Tipleri
Veri türlerini ve veri yapılarını tanımlamak için yeterli tesislerin varlığı
bir dilde okunabilirlik için başka bir önemli yardımdır. Örneğin, bir
içinde Boole türü olmadığından gösterge bayrağı için sayısal tür kullanılır.
dilim. Böyle bir dilde, aşağıdaki gibi bir görevimiz olabilir:
zaman aşımı = 1
Bu ifadenin anlamı belirsizdir, oysa aşağıdakileri içeren bir dilde
Boole türleri, aşağıdakilere sahip olurduk:
zaman aşımı = doğru
Bu ifadenin anlamı son derece açıktır.
1.3.1.4 Sözdizimi Tasarımı
Bir dilin öğelerinin sözdizimi veya biçimi, dil üzerinde önemli bir etkiye sahiptir.
programların okunabilirliği. Aşağıda sözdizimsel tasarımın bazı örnekleri verilmiştir.
okunabilirliği etkileyen seçenekler:
Özel kelimeler. Program görünümü ve dolayısıyla program okunabilirliği güçlü bir şekilde
bir dilin özel sözcüklerinin biçimlerinden etkilenir (örneğin, while ,
sınıf ve için ). Bileşik oluşturma yöntemi özellikle önemlidir.
ifadeler veya ifade grupları, öncelikle kontrol yapılarında. Bazı lan-
göstergeler, gruplar oluşturmak için eşleşen özel kelime veya sembol çiftlerini kullanmıştır.
C ve onun soyundan gelenler, bileşik ifadeleri belirtmek için parantez kullanır. Hepsi
deyim grupları her zaman sonlandırılmış olduğundan bu diller zarar görür.
aynı şekilde, bu da hangi grubun sona erdiğini belirlemeyi zorlaştırıyor.
bir veya sağ ayraç göründüğünde. Fortran 95 ve Ada bunu daha net hale getiriyor
her bir deyim grubu türü için ayrı bir kapanış sözdizimi kullanarak. İçin
örneğin, Ada bir seçim yapısını ve bitiş döngüsünü sonlandırmak için end if kullanır
bir döngü yapısını sonlandırmak için. arasındaki çatışmaya bir örnektir.
C++'da olduğu gibi daha az ayrılmış sözcükle sonuçlanan basitlik ve daha büyük
Ada'da olduğu gibi, daha ayrılmış sözcüklerin kullanılmasından kaynaklanabilecek okunabilirlik.
Bir diğer önemli konu da, bir dilin özel sözcüklerinin kullanılıp kullanılamayacağıdır.
program değişkenleri için isimler olarak kullanılabilir. Eğer öyleyse, ortaya çıkan programlar
çok kafa karıştırıcı olmak. Örneğin, Fortran 95'te Do gibi özel kelimeler
ve End , yasal değişken adlarıdır, bu nedenle bu kelimelerin bir
program özel bir şey çağrıştırabilir veya çağrıştırmayabilir.

Sayfa 34
1.3 Dil Değerlendirme Kriterleri 13
Biçim ve anlam. İfadeleri en azından görünüşleri olacak şekilde tasarlama
kısmen, amaçlarının okunabilirliğe açık bir yardım olduğunu gösterir. anlambilim,
veya anlam, doğrudan sözdiziminden veya biçimden gelmelidir. Bazı durumlarda, bu
ilkesi, aynı veya benzer iki dil yapısı tarafından ihlal edilir.
görünüşte ama belki bağlama bağlı olarak farklı anlamları vardır. İçinde
C, örneğin, ayrılmış statik kelimesinin anlamı ,
görünüşünün bağlamı. Bir işlev içindeki bir değişkenin tanımında kullanılırsa,
değişkenin derleme zamanında oluşturulduğu anlamına gelir. Tanımda kullanılırsa
bir değişkenin tüm fonksiyonların dışında olması, değişkenin yalnızca içinde görünür olduğu anlamına gelir.
tanımının göründüğü dosya; yani, o dosyadan dışa aktarılmaz.
UNIX'in kabuk komutlarıyla ilgili başlıca şikayetlerden biri
(Raymond, 2004), görünüşlerinin her zaman kendilerini ifade etmemesidir.
işlev. Örneğin, UNIX komutunun anlamı grep şu şekilde olabilir:
deşifre sadece ön bilgi ya da belki zeka ve aile yoluyla
UNIX düzenleyicisi ile uyum, ed . Görünümü grep şey çağrıştırır
UNIX'e yeni başlayanlar için. (In ed komut / normal_ifade for a / arama
normal ifadeyle eşleşen alt dize. Bunu g ile önce yapmak
aramanın kapsamının bütün olduğunu belirten global bir komuttur.
dosya düzenleniyor. p ile komutun ardından, şu satırların olduğunu belirtir:
eşleşen alt dize yazdırılacaktır. Yani g /regular_expression / p , ki
açıkça grep olarak kısaltılabilir , içeren bir dosyadaki tüm satırları yazdırır
normal ifadeyle eşleşen alt dizeler.)
1.3.2 Yazılabilirlik
Yazılabilirlik, bir dilin program oluşturmak için ne kadar kolay kullanılabileceğinin bir ölçüsüdür.
seçilen bir problem alanı için. etkileyen dil özelliklerinin çoğu
okunabilirlik ayrıca yazılabilirliği de etkiler. Bu, doğrudan şu gerçeğinden kaynaklanmaktadır:
Bir program yazma süreci, programcının sık sık programı tekrar okumasını gerektirir.
zaten yazılmış olan programın bir parçası.
Okunabilirlikte olduğu gibi, yazılabilirlik de bu bağlamda dikkate alınmalıdır.
bir dilin hedef problem alanının metni. sadece mantıklı değil
belirli bir uygulama alanında iki dilin yazılabilirliğini karşılaştırın
biri bu uygulama için tasarlanırken diğeri tasarlanmamıştı. Örneğin,
Visual BASIC (VB) ve C'nin yazılabilirlikleri için önemli ölçüde farklıdır.
VB'nin ideal olduğu bir grafik kullanıcı arayüzüne sahip bir program oluşturmak.
Yazılabilirlikleri de sistem programları yazmak için oldukça farklıdır;
C'nin tasarlandığı bir işletim sistemi olarak.
Aşağıdaki alt bölümlerde en önemli özellikler açıklanmaktadır.
bir dilin yazılabilirliğini etkiler.
1.3.2.1 Basitlik ve Ortogonallik
Bir dilin çok sayıda farklı yapısı varsa, bazı programcılar
hepsine aşina olmayabilir. Bu durum yanlış kullanıma yol açabilir.
daha zarif veya daha fazla olabilecek bazı özellikler ve diğerlerinin kullanılmaması

Sayfa 35
14
1. Bölüm Ön Hazırlıklar
kullanılanlardan daha verimli veya her ikisi. Hatta belirtildiği gibi mümkün olabilir
Hoare (1973), bilinmeyen özellikleri yanlışlıkla, tuhaf sonuçlarla kullanmak için.
Bu nedenle, daha az sayıda ilkel yapı ve tutarlı bir dizi
onları birleştirmek için kurallar (yani, ortogonallik) basit olmaktan çok daha iyidir.
çok sayıda ilkel öğeye sahip olmak. Bir programcı, bir soruna bir çözüm tasarlayabilir.
Sadece basit bir dizi ilkel yapıyı öğrendikten sonra karmaşık problem.
Öte yandan, çok fazla ortogonallik yazı yazmak için zararlı olabilir.
Yetenek. Programlardaki hatalar, neredeyse herhangi bir kombinasyonu olduğunda tespit edilemeyebilir.
ilkel yasaldır. Bu, keşfedilemeyen kod saçmalıklarına yol açabilir.
derleyici tarafından.
1.3.2.2 Soyutlama Desteği
Özetle, soyutlama , karmaşıklığı tanımlama ve daha sonra kullanma yeteneği anlamına gelir.
ayrıntıların çoğunun göz ardı edilmesine izin verecek şekilde yapılar veya işlemler.
Soyutlama, çağdaş programlama dili tasarımında anahtar bir kavramdır.
Bu, modern prodüksiyonda soyutlamanın oynadığı merkezi rolün bir yansımasıdır.
gram tasarım metodolojileri. Bir programın izin verdiği soyutlama derecesi-
ming dili ve ifadesinin doğallığı bu nedenle önemlidir.
onun yazılabilirliği. Programlama dilleri iki farklı kategoriyi destekleyebilir.
soyutlama, süreç ve veri.
Basit bir süreç soyutlama örneği, bir alt programın kullanılmasıdır.
bir programda birkaç kez gerekli olan bir sıralama algoritması uygular. İle-
alt program dışında, sıralama kodunun her yerde çoğaltılması gerekir.
nerede ihtiyaç duyulduysa, bu da programı çok daha uzun ve daha uzun hale getirecektir.
yazmak sıkıcı. Belki daha da önemlisi, alt program kullanılmadıysa,
sıralama alt programını kullanan kod, sıralama algoritması ile karmaşık hale gelir.
ayrıntılar, bu kodun akışını ve genel amacını büyük ölçüde gizler.
Veri soyutlamaya bir örnek olarak, tamsayıları depolayan bir ikili ağaç düşünün.
düğümlerindeki veriler. Böyle bir ikili ağaç genellikle bir dilde uygulanır.
bir yığın ile işaretçileri ve dinamik depolama yönetimini desteklemeyen,
Fortran 77 gibi, üç paralel tamsayı dizisi olarak, burada iki tamsayı
yavru düğümleri belirtmek için alt simge olarak kullanılır. C++ ve Java'da bu ağaçlar
basit bir sınıf biçiminde bir ağaç düğümünün soyutlaması kullanılarak uygulanır
iki işaretçi (veya referans) ve bir tamsayı ile. İkincisinin doğallığı
temsil, ikili ağaçları kullanan bir program yazmayı çok daha kolaylaştırır
Fortran 77'de bir tane yazmaktansa bu dillerde.
dilin problem çözüm alanının problem alanına daha yakın olmasıdır.
Soyutlama için genel destek, açıkça önemli bir faktördür.
bir dilin yazılabilirliği.
1.3.2.3 Dışavurumculuk
Bir dilde ifade, birkaç farklı özelliğe atıfta bulunabilir. İçinde
APL gibi bir dil (Gilman ve Rose, 1976), çok
çok sayıda hesaplamanın gerçekleştirilmesine izin veren güçlü operatörler

Sayfa 36
1.3 Dil Değerlendirme Kriterleri 15
çok küçük bir programla. Daha yaygın olarak, bir dilin sahip olduğu anlamına gelir.
hantal olmaktan ziyade nispeten uygun, hesaplama belirleme yolları
tion. Örneğin, C'de, count++ gösterimi daha kullanışlı ve daha kısadır.
daha saymak = saymak + 1 . Ayrıca, Ada'daki ve ardından Boole operatörü bir
Boolean ifadesinin kısa devre değerlendirmesini belirtmenin uygun yolu.
Java'da for ifadesinin dahil edilmesi, sayma döngülerinin yazılmasını kolaylaştırır
while kullanımından daha fazla , ki bu da mümkündür. Bütün bunlar artışı
bir dilin yazılabilirliği.
1.3.3 Güvenilirlik
Bir program, aşağıdaki özelliklere uygun olarak çalışıyorsa, güvenilir olduğu söylenir.
tüm koşullar. Aşağıdaki alt bölümlerde çeşitli dil özellikleri anlatılmaktadır.
Belirli bir alandaki programların güvenilirliği üzerinde önemli bir etkiye sahip olan
dilim.
1.3.3.1 Tip Kontrolü
Tip kontrolü , belirli bir programda basitçe tip hatalarını test etmektir.
derleyici tarafından veya program yürütme sırasında. Tip kontrolü önemli bir
dil güvenilirliğinde tant faktörü. Çünkü çalışma zamanı tip kontrolü masraflıdır.
sive, derleme zamanı tür denetimi daha çok tercih edilir. Ayrıca, daha önceki
programlardaki hatalar tespit edilirse, gerekli olanı yapmak o kadar ucuz olur
onarımlar. Java tasarımı, neredeyse tüm değişken türlerinin kontrollerini gerektirir.
ve derleme zamanında ifadeler. Bu, çalıştırma sırasında tip hatalarını neredeyse ortadan kaldırır
Java programlarında zaman. Tipler ve tip kontrolü derinlemesine tartışılmaktadır.
Bölüm 6.
Derleme zamanında veya çalıştırma sırasında kontrol yazılamamasının nasıl başarısız olduğuna bir örnek
zaman, sayısız program hatasına yol açmıştır, alt program parametrelerinin kullanılmasıdır.
orijinal C dilinde (Kernighan ve Ritchie, 1978). Bu dilde,
bir işlev çağrısındaki gerçek parametrenin tipini belirlemek için kontrol edilmedi
türünün karşılık gelen resmi parametreninkiyle eşleşip eşleşmediği
işlev. Bir çağrıda gerçek bir parametre olarak int tipi bir değişken kullanılabilir.
biçimsel parametresi olarak bir kayan nokta türü bekleyen bir işlev ve hiçbiri
derleyici veya çalışma zamanı sistemi tutarsızlığı algılayamaz. Örneğin,
çünkü 23 tamsayısını temsil eden bit dizisi, esasen
bir tamsayı 23'e gönderilirse, bir kayan nokta 23'ü temsil eden bit dizisi
kayan nokta parametresi bekleyen fonksiyon, parametrenin herhangi bir kullanımı
fonksiyon saçmalık üretecektir. Ayrıca, bu tür sorunlar genellikle
teşhis etmek zor. 3 C'nin şu anki sürümü bu sorunu ortadan kaldırdı
tüm parametrelerin tip kontrol edilmesini gerektirerek. Alt programlar ve parametre-
geçme teknikleri Bölüm 9'da tartışılmaktadır.
3. Bu ve benzeri sorunlara yanıt olarak, UNIX sistemleri bir yardımcı program içerir.
C programlarını bu tür sorunlar için kontrol eden adlandırılmış tiftik.

Sayfa 37
16
1. Bölüm Ön Hazırlıklar
1.3.3.2 İstisna İşleme
Bir programın çalışma zamanı hatalarını engelleme yeteneği (ve diğer olağandışı
program tarafından algılanabilen koşullar), düzeltici önlemler alın ve ardından
devam etmek, güvenilirliğe açık bir yardımcıdır. Bu dil olanağına istisna denir.
işlem yönetimi . Ada, C++, Java ve C# için kapsamlı yetenekler içerir.
istisna işleme, ancak bu tür tesisler birçok ülkede pratik olarak mevcut değildir.
C ve Fortran da dahil olmak üzere yaygın olarak kullanılan diller. İstisna işleme dis-
14. bölümde tartışıldı.
1.3.3.3 Örtüşme
Gevşek bir şekilde tanımlanmış, takma ad , iki veya daha fazla farklı isme sahip olmaktır .
aynı bellek hücresine erişmek için kullanılır. Takma adların artık yaygın olarak kabul
bir programlama dilinde tehlikeli bir özelliktir. Çoğu programlama lan-
göstergeler bir tür örtüşmeye izin verir; örneğin, işaret edecek şekilde ayarlanmış iki işaretçi
çoğu dilde mümkün olan aynı değişken. Böyle bir programda,
programcı her zaman bir ile gösterilen değeri değiştirmenin
ikisinden biri, diğeri tarafından referans verilen değeri değiştirir. Bazı takma ad türleri,
Bölüm 5 ve 9'da açıklandığı gibi, bir dilin tasarımıyla yasaklanabilir.
Bazı dillerde, lan-
guage'nin veri soyutlama tesisleri. Diğer diller, takma ad vermeyi büyük ölçüde kısıtlar
güvenilirliklerini artırmak.
1.3.3.4 Okunabilirlik ve Yazılabilirlik
Hem okunabilirlik hem de yazılabilirlik güvenilirliği etkiler. Bir programda yazılmış
gerekli algoritmaları ifade etmenin doğal yollarını desteklemeyen dil
mutlaka doğal olmayan yaklaşımlar kullanacaktır. Doğal olmayan yaklaşımlar daha az olasıdır
tüm olası durumlar için doğru olması. Bir programın yazılması ne kadar kolaysa,
doğru olması daha olasıdır.
Okunabilirlik, hem yazma hem de bakım aşamalarında güvenilirliği etkiler
yaşam döngüsünden. Okunması zor programları hem yazması zor
ve değiştirmek için.
1.3.4 Maliyet
Bir programlama dilinin toplam maliyeti, birçok programlama dilinin bir fonksiyonudur.
özellikler.
Birincisi, dili kullanmak için programcı yetiştirmenin maliyeti vardır.
dilin ve deneyimin basitliğinin ve ortogonalliğinin bir fonksiyonudur.
programcıların işi. Daha güçlü diller gerekli olmasa da
öğrenmesi daha zordur, genellikle öyledir.
İkincisi, dilde program yazmanın maliyeti var. Bu bir
kısmen yakınlığına bağlı olan dilin yazılabilirliğinin işlevi
belirli bir uygulamaya yönelik amaç olarak. Tasarım için özgün çabalar ve

Sayfa 38
1.3 Dil Değerlendirme Kriterleri 17
yüksek seviyeli dilleri uygulamak, maliyetleri düşürme arzusundan kaynaklandı
yazılım oluşturma.
Hem eğitim programcılarının maliyeti hem de program yazmanın maliyeti
bir dil, iyi bir programlama ortamında önemli ölçüde azaltılabilir.
Programlama ortamları Bölüm 1.8'de tartışılmaktadır.
Üçüncüsü, dilde program derlemenin maliyeti vardır. Büyük bir
Ada'nın erken kullanımının önündeki engel, işletme maliyetinin aşırı derecede yüksek olmasıydı.
birinci nesil Ada derleyicileri. Bu sorun azaltıldı
geliştirilmiş Ada derleyicilerinin görünümü.
Dördüncüsü, bir dilde yazılmış programları yürütmenin maliyeti oldukça fazladır.
bu dilin tasarımından etkilenir. Birçok çalışma zamanı gerektiren bir dil
tür denetimleri, dosyanın kalitesinden bağımsız olarak hızlı kod yürütülmesini engelleyecektir.
derleyici. Uygulama verimliliği tasarımdaki en önemli endişe olmasına rağmen
erken dillerden, şimdi daha az önemli olarak kabul edilir.
Derleme maliyeti ve yürütme arasında basit bir değiş tokuş yapılabilir
derlenmiş kodun hızı. Optimizasyon , koleksiyona verilen addır.
derleyicilerin boyutu azaltmak ve/veya yürütmeyi artırmak için kullanabileceği teknikler
ürettikleri kodun tion hızı. Çok az veya hiç optimizasyon yapılmazsa,
pilasyon, üretmek için önemli bir çaba gösterilmesinden çok daha hızlı yapılabilir.
optimize edilmiş kod İki alternatif arasındaki seçim, aşağıdakilerden etkilenir:
derleyicinin kullanılacağı ortam. Başlangıç ​​için bir laboratuvarda
sırasında programlarını sıklıkla birçok kez derleyen programlama öğrencileri
geliştirme ancak yürütme sırasında çok az kod kullanın (programları küçüktür ve
bunlar yalnızca bir kez doğru şekilde yürütülmelidir), çok az optimizasyon yapılmalı veya hiç yapılmamalıdır.
Derlenmiş programların çok sayıda yürütüldüğü bir üretim ortamında
geliştirmeden birkaç kez sonra, kodu optimize etmek için ekstra maliyet ödemek daha iyidir.
Bir dilin maliyetindeki beşinci faktör, dil uygulamasının maliyetidir.
akıl yürütme sistemi. hızlı kabul görmesini açıklayan faktörlerden biri
Java, kısa bir süre sonra ücretsiz derleyici/yorumlayıcı sistemlerin kullanıma sunulmasıdır.
tasarımı yayınlandı. Uygulama sistemi aşağıdakilerden biri olan bir dil
pahalıdır veya yalnızca pahalı donanımlarda çalışır, çok daha küçük bir şansa sahip olur
yaygın olarak kullanılmaya başlanmasıdır. Örneğin, birinci nesil Ada'nın yüksek maliyeti
derleyiciler, Ada'nın ilk günlerinde popüler olmasını önlemeye yardımcı oldu.
Altıncısı, zayıf güvenilirliğin maliyeti var. Yazılım kritik bir sistemde başarısız olursa
bir nükleer santral veya tıbbi kullanım için bir X-ray makinesi gibi tem, maliyet
çok yüksek olabilir. Kritik olmayan sistemlerin arızaları da çok pahalı olabilir.
Gelecekteki iş kaybı veya kusurlu yazılım sistemleri nedeniyle davalar açısından.
Son değerlendirme, aşağıdakileri içeren programları sürdürmenin maliyetidir:
yeni işlevler eklemek için hem düzeltmeler hem de değişiklikler. yazılım maliyeti
bakım, başta okuma olmak üzere bir dizi dil özelliğine bağlıdır.
Yetenek. Çünkü bakım genellikle orijinalinden farklı kişiler tarafından yapılır.
Yazılımın yazarı, zayıf okunabilirlik, görevi son derece zorlaştırabilir.
Yazılım sürdürülebilirliğinin önemi göz ardı edilemez. sahip
Göreceli olarak uzun ömürlü büyük yazılım sistemleri için,
bakım maliyetleri, geliştirme maliyetinin iki ila dört katı kadar yüksek olabilir
maliyetleri (Sommerville, 2005).

Sayfa 39
18
1. Bölüm Ön Hazırlıklar
Dil maliyetlerine katkıda bulunanlardan üçü en önemlisidir: program
geliştirme, bakım ve güvenilirlik. Çünkü bunlar yazılabilirliğin işlevleridir.
Bu iki değerlendirme kriteri sırasıyla en önemlileridir.
Elbette, programı değerlendirmek için bir dizi başka kriter kullanılabilir.
ming dilleri. Bir örnek taşınabilirlik veya programların kullanım kolaylığıdır.
bir uygulamadan diğerine taşınabilir. Taşınabilirlik en güçlü
dilin standardizasyon derecesinden etkilenir. Bazı diller,
BASIC gibi, hiçbir şekilde standartlaştırılmamış, bu dillerde programlar yapmak
bir uygulamadan diğerine geçmek çok zor. Standardizasyon
zaman alıcı ve zor bir süreç. Bir komite üretim için çalışmaya başladı
1989'da standart bir C++ sürümü. 1998'de onaylandı.
Genellik (geniş bir uygulama yelpazesine uygulanabilirlik) ve iyi-
tanımlılık (dilin resmi tanımlamasının eksiksizliği ve kesinliği
belge) diğer iki kriterdir.
Çoğu kriter, özellikle okunabilirlik, yazılabilirlik ve güvenilirlik, ikisi de değildir.
ne kesin olarak tanımlanmış ne de tam olarak ölçülebilir. Yine de, bunlar yararlı kavramlardır.
ve programın tasarımı ve değerlendirilmesi hakkında değerli bilgiler sağlarlar.
ming dilleri.
Değerlendirme kriterleri hakkında son bir not: dil tasarım kriterleri tartılır
farklı bakış açılarından farklı. Dil uygulayıcıları endişeli
öncelikle yapı ve özelliklerin uygulanmasının zorluğu ile
dilim. Dil kullanıcıları önce yazılabilirlik ve okunabilirlik konusunda endişeleniyor
sonra. Dil tasarımcıları muhtemelen zarafeti ve
yaygın kullanımı çekmek. Bu özellikler genellikle birbiriyle çelişir.
1.4 Dil Tasarımına Etkiler
Bölüm 1.3'te açıklanan faktörlere ek olarak, birkaç başka faktör de etkilidir.
Programlama dillerinin temel tasarımı. Bunlardan en önemlileri
bilgisayar mimarisi ve programlama tasarım metodolojileridir.
1.4.1 Bilgisayar Mimarisi
Bilgisayarların temel mimarisinin dil üzerinde derin bir etkisi oldu.
tasarım. Son 50 yılın popüler dillerinin çoğu tasarlanmıştır.
von Neumann mimarisi olarak adlandırılan yaygın bilgisayar mimarisi etrafında
tecture , yaratıcılarından biri olan John von Neumann'dan ("von" olarak telaffuz edilir) sonra
Noyman”). Bu dillere zorunlu diller denir . Bir von Neu-
mann bilgisayarında hem veriler hem de programlar aynı bellekte saklanır. bu
komutları yürüten merkezi işlem birimi (CPU),
hafıza. Bu nedenle, talimatlar ve veriler aşağıdakilerden iletilmeli veya iletilmelidir.
CPU'ya bellek. CPU'daki işlemlerin sonuçları geri taşınmalıdır
hafızaya. 1940'lardan beri üretilen neredeyse tüm dijital bilgisayarlar,
von Neumann mimarisi üzerine. Bir von Neumann'ın genel yapısı
bilgisayar Şekil 1.1'de gösterilmiştir.

Sayfa 40
1.4 Dil Tasarımına Etkiler 19
Von Neumann mimarisi nedeniyle impera-
diller, bellek hücrelerini modelleyen değişkenlerdir; atama durumu-
borulama işlemine dayanan; ve yinelemeli formu
bu konuda tekrarı uygulamanın en etkili yolu olan tekrar
mimari. İfadelerdeki işlenenler bellekten CPU'ya iletilir,
ve ifadenin değerlendirilmesinin sonucu bellek hücresine geri gönderilir
atamanın sol tarafı ile temsil edilir. Von Neumann'da yineleme hızlı
bilgisayarlar, çünkü talimatlar bitişik bellek hücrelerinde saklanır ve
bir kod bölümünün yürütülmesini tekrarlamak için yalnızca bir dal talimatı gerekir.
Bu verimlilik, yineleme için yinelemenin kullanılmasını engeller.
bazen daha doğaldır.
Bir von Neumann mimarisinde bir makine kodu programının yürütülmesi
bilgisayar, getirme-yürütme döngüsü adı verilen bir işlemde gerçekleşir . Daha önce belirtildiği gibi,
programlar bellekte bulunur, ancak CPU'da yürütülür. için her talimat
yürütülecek bellekten işlemciye taşınmalıdır. adresi
yürütülecek bir sonraki talimat, program adı verilen bir kayıt defterinde tutulur.
sayaç . Getir-yürüt döngüsü basitçe aşağıdaki şekilde açıklanabilir.
algoritma:
program sayacını başlat
sonsuza kadar tekrar et
program sayacının gösterdiği talimatı getir
program sayacını bir sonraki talimatı gösterecek şekilde artırın
talimatın kodunu çöz
talimatı uygula
tekrarı bitir
aritmetik ve
mantık birimi
Kontrol
birim
Bellek (hem talimatları hem de verileri depolar)
Talimatlar ve veriler
Giriş ve çıkış cihazları
sonuçları
operasyonlar
Merkezi işlem birimi
Şekil 1.1
von Neumann
bilgisayar Mimarisi

Sayfa 41
20
1. Bölüm Ön Hazırlıklar
Algoritmadaki "talimatın kodunu çözme" adımı, talimatın
hangi eylemi belirlediğini belirlemek için incelenir. Program yürütme sonlandırılır
gerçek bir bilgisayarda bir durma olmasına rağmen, bir durdurma talimatı ile karşılaşıldığında
talimat nadiren yürütülür. Bunun yerine, işletim sisteminden kontrol transferleri
yürütülmesi için bir kullanıcı programına ve ardından işletim sistemine geri
kullanıcı programı yürütmesi tamamlandığında. olduğu bir bilgisayar sisteminde
belirli bir zamanda birden fazla kullanıcı programı bellekte olabilir, bu işlem
çok daha karmaşıktır.
Daha önce belirtildiği gibi, işlevsel veya uygulamalı bir dil, içinde bulunduğu dildir.
birincil hesaplama yöntemi, verilen parametrelere fonksiyonları uygulamaktır.
Programlama, herhangi bir değişken olmadan işlevsel bir dilde yapılabilir.
atama ifadeleri olmadan zorunlu dillerde kullanılan yetenekler ve
yineleme olmadan. Her ne kadar birçok bilgisayar bilimci açıklamış olsa da
Scheme gibi işlevsel dillerin sayısız faydalarının olması pek olası değildir.
non-von Neumann bilgisayarı oluşana kadar zorunlu dillerin yerini alacaktır.
Programların işlevsel dillerde verimli bir şekilde yürütülmesine izin verecek şekilde tasarlanmıştır.
Bu gerçeğe yakınanlar arasında en etkili olanı John Backus'tur.
(1978), Fortran'ın orijinal versiyonunun baş tasarımcısı.
Zorunlu programlama dillerinin yapısı her ne kadar
yetenekler ve eğilimler yerine bir makine mimarisinde modellenmiştir.
programlama dillerinin kullanıcılarının çoğu, bazıları zorunlu kullanmanın
diller, işlevsel bir dil kullanmaktan bir şekilde daha doğaldır. Yani, bunlar
insanlar, işlevsel programların zorunlu olduğu kadar verimli olsa bile
programlarda, zorunlu programlama dillerinin kullanımı hala baskın olacaktır.
1.4.2 Programlama Tasarım Metodolojileri
1960'ların sonu ve 1970'lerin başı, büyük ölçüde başlayan yoğun bir analiz getirdi.
hem yazılım geliştirmenin yapısal programlama hareketiyle
süreç ve programlama dili tasarımı.
Bu araştırmanın önemli bir nedeni, ana maliyetlerdeki kaymaydı.
donanım maliyetleri azaldıkça ve pro-
gramer maliyetleri arttı. Programcı verimliliğindeki artışlar nispeten
küçük. Ayrıca, giderek daha büyük ve daha karmaşık problemler ortaya çıkıyordu.
bilgisayarlar tarafından çözülmüştür. Simüle etmek için basitçe denklem kümelerini çözmek yerine
uydu izleri, 1960'ların başında olduğu gibi, büyük programlar için programlar yazıldı.
ve büyük petrol arıtma tesislerini kontrol etmek gibi karmaşık görevler ve
dünya çapında havayolu rezervasyon sistemleri sağlamak.
Sonuç olarak ortaya çıkan yeni yazılım geliştirme metodolojileri
1970'lerin araştırmalarının çoğuna yukarıdan aşağıya tasarım ve adım adım rafine etme adı verildi.
ment. Keşfedilen birincil programlama dili eksiklikleri
tip kontrolünün eksikliği ve kontrol ifadelerinin yetersizliği
(gotoların kapsamlı kullanımını gerektirir).
1970'lerin sonlarında, prosedür odaklıdan veri odaklı pro-
gram tasarım metodolojileri başladı. Basitçe söylemek gerekirse, veri odaklı yöntemler vurgu-
Problemleri çözmek için soyut veri tiplerinin kullanımına odaklanan boyut veri tasarımı.

Sayfa 42
1.5 Dil Kategorileri 21
Veri soyutlamanın yazılım sistem tasarımında etkin bir şekilde kullanılabilmesi için,
uygulama için kullanılan diller tarafından desteklenmelidir. İlk lan-
SIMULA 67, veri soyutlaması için sınırlı destek bile sağlamanın göstergesiydi.
(Birtwistle ve diğerleri, 1973), ancak bu dil kesinlikle ileri sürülmemiştir.
popülerlik bu yüzden. Veri soyutlamanın faydaları yaygın değildi
1970'lerin başına kadar tanındı. Ancak, o zamandan beri tasarlanan dillerin çoğu
1970'lerin sonlarında, Bölüm 11'de ayrıntılı olarak tartışılan veri soyutlamayı destekler.
Veri odaklı yazılım geliştirmenin evrimindeki son adım,
1980'lerin başında başlayan nesne yönelimli tasarımdır. Nesne odaklı
metodoloji, işlemeyi kapsayan veri soyutlama ile başlar.
veri nesneleri ve verilere erişimi kontrol eder ve kalıtım ve dinamik ekler
yöntem bağlama. Kalıtım, mirası büyük ölçüde geliştiren güçlü bir kavramdır.
mevcut yazılımın potansiyel olarak yeniden kullanılması, böylece önemli olma olasılığı
yazılım geliştirme verimliliğinde artış olamaz. Bu önemli bir faktör
nesne yönelimli dillerin popülaritesinin artması. Dinamik (çalışma zamanı)
yöntem bağlama, kalıtımın daha esnek kullanımına izin verir.
Nesne yönelimli programlama, bir dil ile birlikte geliştirildi.
kavramlarını destekledi: Smalltalk (Goldberg ve Robson, 1989). Rağmen
Smalltalk hiçbir zaman diğer diller kadar yaygın olarak kullanılmadı.
nesne yönelimli programlama artık en popüler zorunlu dilin bir parçası.
Ada 95 (ARM, 1995), Java, C++ ve C# dahil. Nesne odaklı
kavramlar ayrıca CLOS'ta işlevsel programlamaya da girmiştir.
(Bobrow ve diğerleri, 1988) ve F# (Syme ve diğerleri, 2010) ile mantıksal programlama
Prolog++'da (Moss, 1994). Nesne yönelimli programlama için dil desteği
Bölüm 12'de ayrıntılı olarak tartışılmaktadır.
Prosedür yönelimli programlama, bir anlamda verinin tam tersidir.
odaklı programlama Veri odaklı yöntemler artık yazılıma hakim olsa da,
eşya geliştirme, prosedür odaklı yöntemlerden vazgeçilmemiştir.
Aksine, son yıllarda çok sayıda araştırma yapılmıştır.
özellikle eşzamanlılık alanında prosedür odaklı programlama.
Bu araştırma çabaları, dil olanaklarına duyulan ihtiyacı beraberinde getirdi.
eşzamanlı program birimleri oluşturma ve kontrol etme. Ada, Java ve C# şunları içerir:
bu tür yetenekler. Eşzamanlılık Bölüm 13'te ayrıntılı olarak tartışılmaktadır.
Yazılım geliştirme metodolojilerindeki tüm bu evrimsel adımlar,
onları desteklemek için yeni dil yapılarına.
1.5 Dil Kategorileri
Programlama dilleri genellikle dört bölmeye ayrılır: zorunlu,
işlevsel, mantık ve nesne yönelimli. Ancak, dilleri dikkate almıyoruz.
ayrı bir kategori oluşturmak için nesne yönelimli programlamayı destekleyen
Diller. Destekleyen en popüler dillerin nasıl olduğunu açıkladık.
nesne yönelimli programlama zorunlu dillerden doğdu. Rağmen
nesne yönelimli yazılım geliştirme paradigması, diğerlerinden önemli ölçüde farklıdır.
genellikle zorunlu dillerle kullanılan prosedür odaklı paradigma,

Sayfa 43
22
1. Bölüm Ön Hazırlıklar
nesne yönelimli pro-
gramaj yoğun değildir. Örneğin, ifadeler, atama durumu-
C ve Java'nın komutları ve kontrol ifadeleri hemen hemen aynıdır. (Diğer taraftan, başka bir açıdan
yandan, Java'nın dizileri, alt programları ve semantiği, Java'dan çok farklıdır.
C'ninkiler.) Destekleyen işlevsel diller için benzer ifadeler yapılabilir.
port nesne yönelimli programlama.
Başka bir dil türü olan görsel dil, impera'nın bir alt kategorisidir.
diller. En popüler görsel diller .NET dilleridir. Bunlar
diller (veya uygulamaları), sürükle ve bırak oluşturma için yetenekler içerir.
kod bölümlerinin oluşumu. Bu tür diller bir zamanlar dördüncü nesil olarak adlandırılıyordu.
diller, bu isim kullanımdan düşmüş olsa da. Görsel diller sağlar
programlara grafiksel kullanıcı arayüzleri oluşturmanın basit bir yolu. Örneğin, kullanarak
.NET dillerinde yazılım geliştirmek için Visual Studio, kod üretmek için bir
bir düğme veya metin kutusu gibi bir form denetiminin görüntülenmesi, tek bir
tuş vuruşu. Bu yetenekler artık tüm .NET dillerinde mevcuttur.
Bazı yazarlar betik dillerine ayrı bir pro-
gramer dilleri. Ancak, bu kategorideki diller birbirine bağlıdır
uygulama yöntemlerinden, kısmi veya tam yorumlamadan daha çok
ortak bir dil tasarımı. Genellikle komut dosyası olarak adlandırılan diller
Perl, JavaScript ve Ruby gibi diller zorunlu dillerdir.
Her anlamda.
Mantık programlama dili, kural tabanlı bir dil örneğidir.
Zorunlu bir dilde, bir algoritma çok ayrıntılı olarak belirtilir ve
talimatların veya ifadelerin özel yürütme sırası dahil edilmelidir.
Ancak kural tabanlı bir dilde kurallar belirli bir sıra ile belirtilmez.
ve dil uygulama sistemi bir sıra seçmelidir.
İstenilen sonucu elde etmek için kurallar kullanılır. Yazılım geliştirmeye yönelik bu yaklaşım,
opment, diğer iki kategoride kullanılanlardan kökten farklıdır.
ve açıkçası tamamen farklı bir dil türü gerektirir. Prolog,
en yaygın olarak kullanılan mantık programlama dili ve mantık programlama
Bölüm 16'da tartışılmaktadır.
Son yıllarda, yeni bir dil kategorisi ortaya çıktı, işaretleme/
hibrit dillerin programlanması. İşaretleme dilleri programlama değildir
Diller. Örneğin, en yaygın kullanılan biçimlendirme dili olan HTML,
Web belgelerindeki bilgilerin düzenini belirtmek için kullanılır. Ancak, bazıları
programlama yeteneği, HTML ve XML'in bazı uzantılarına sızmıştır.
Bunlar arasında Java Sunucu Sayfaları Standart Etiket Kitaplığı (JSTL) ve
Genişletilebilir Stil Sayfası Dil Dönüşümleri (XSLT). Bunların ikisi de
Bölüm 2'de kısaca tanıtılan bu diller herhangi bir dille karşılaştırılamaz.
tam programlama dillerinden biridir ve bu nedenle tartışılmayacaktır.
2. Bölümden sonra.
Son 50 yılda bir dizi özel amaçlı dil ortaya çıktı.
Bunlar, üretmek için kullanılan Rapor Program Üreticisinden (RPG) farklıdır.
iş raporları; için kullanılan Otomatik Programlanmış Araçlara (APT)
programlanabilir takım tezgahlarını öğretmek; Genel Amaçlı Simülasyon Sistemine
sistem simülasyonu için kullanılan tem (GPSS). Bu kitap tartışmıyor

Sayfa 44
1.7 Uygulama Yöntemleri 23
özel amaçlı diller, öncelikle dar uygulanabilirlikleri ve
onları diğer dillerle karşılaştırmanın zorluğu.
1.6 Dil Tasarımı Ödünleri
Bölüm 1.3'te açıklanan programlama dili değerlendirme kriterleri
dil tasarımı için bir çerçeve sağlar. Ne yazık ki, bu çerçeve
kendi kendine çelişkili. Dil tasarımı üzerine kapsamlı makalesinde, Hoare (1973)
“O kadar önemli ama birbiriyle çelişen kriterler var ki, onların
uzlaşma ve memnuniyet önemli bir mühendislik görevidir.”
Çatışan iki kriter güvenilirlik ve yürütme maliyetidir. Örneğin,
Java dili tanımı, dizi öğelerine yapılan tüm referansların kontrol edilmesini gerektirir
Endeks veya endekslerin yasal aralıklarında olmasını sağlamak. Bu adım harika bir
çok sayıda başvuru içeren Java programlarının yürütme maliyetiyle ilgilenir.
dizi elemanlarına bağlıdır. C, dizin aralığı denetimi gerektirmez, bu nedenle C programları
Java programları semantik olarak eşdeğer Java programlarından daha hızlı yürütülür.
daha güvenilirdirler. Java tasarımcıları, güvenilirlik için yürütme verimliliğini takas etti.
Doğrudan tasarıma yol açan çelişkili kriterlere başka bir örnek olarak
takaslar, APL örneğini düşünün. APL, güçlü bir operatör grubu içerir
dizi işlenenleri için. Operatör sayısının fazla olması nedeniyle
operatörleri temsil etmek için APL'ye çok sayıda yeni sembolün dahil edilmesi gerekiyordu.
Ayrıca, birçok APL operatörü tek, uzun ve karmaşık bir ifadede kullanılabilir.
Bu yüksek derecede dışavurumculuğun bir sonucu, aşağıdakileri içeren uygulamalar için:
Birçok dizi işleminde, APL çok yazılabilir. Nitekim, büyük miktarda
hesaplama çok küçük bir programda belirtilebilir. Diğer bir sonuç ise
APL programları çok zayıf okunabilirliğe sahiptir. Kompakt ve özlü bir ifade
belirli bir matematiksel güzelliğe sahiptir ama onun dışında herkes için zordur.
anlamak için programcı. Tanınmış yazar Daniel McCracken (1970)
bir keresinde dört satırlık bir APL'yi okuyup anlamasının dört saat sürdüğünü kaydetti.
programı. APL'nin tasarımcısı, okunabilirliği yazılabilirlik için takas etti.
Yazılabilirlik ve güvenilirlik arasındaki çelişki, lansmanda yaygın bir çelişkidir.
guaj tasarımı. C++ işaretçileri çeşitli şekillerde manipüle edilebilir,
Bu, verilerin son derece esnek adreslenmesini destekler. Potansiyel güven nedeniyle
işaretçilerle ilgili yetenek sorunları, Java'ya dahil değildirler.
Dil tasarımı (ve değerlendirme) kriterleri arasındaki çelişki örnekleri
bol; bazıları ince, diğerleri açıktır. Bu nedenle, görevin açık olduğu açıktır.
bir programlama dili tasarlarken yapıları ve özellikleri seçme
birçok taviz ve takas gerektirir.
1.7 Uygulama Yöntemleri
Bölüm 1.4.1'de açıklandığı gibi, bir bilgisayarın iki ana bileşeni
dahili belleği ve işlemcisidir. Dahili bellek için kullanılır
programları ve verileri depolar. İşlemci sağlayan bir devreler topluluğudur.

Sayfa 45
24
1. Bölüm Ön Hazırlıklar
gibi bir dizi ilkel işlemin veya makine talimatlarının gerçekleştirilmesi
aritmetik ve mantık işlemleri için olanlar. Çoğu bilgisayarda, bunlardan bazıları
bazen makro komutlar olarak da adlandırılan komutlar aslında
tanımlanan ve mikro talimatlar adı verilen bir dizi talimatla ifade edilir.
daha da düşük bir seviyede. Mikro talimatlar yazılım tarafından asla görülmediğinden,
burada daha fazla tartışılmayacaktır.
Bilgisayarın makine dili, onun talimat setidir. İçinde
diğer destekleyici yazılımların olmaması, kendi makine dilinin tek
çoğu donanım bilgisayarının "anladığı" dil. Teorik olarak bir kom-
puter, belirli bir üst düzey dil ile tasarlanabilir ve oluşturulabilir.
makine dili, ancak çok karmaşık ve pahalı olurdu. Üstelik,
son derece esnek olmayacaktı, çünkü zor olurdu (ama imkansız değil)
diğer üst düzey dillerle kullanmak için. Daha pratik makine tasarımı
seçim, donanımda aşağıdakileri sağlayan çok düşük seviyeli bir dil uygular.
en yaygın olarak ihtiyaç duyulan ilkel işlemler ve sistem yazılımı gerektirir.
daha yüksek seviyeli dillerdeki programlara bir arayüz oluşturun.
Bir dil uygulama sistemi, bir iletişimdeki tek yazılım olamaz.
bilgisayar. Ayrıca, işletim sistemi adı verilen geniş bir program koleksiyonu da gereklidir.
tem, makine dilinden daha yüksek düzeyde ilkel öğeler sağlar.
Bu ilkeller sistem kaynak yönetimi, giriş ve çıkış işlemleri sağlar.
bir dosya yönetim sistemi, metin ve/veya program düzenleyicileri ve çeşitli
diğer yaygın olarak ihtiyaç duyulan işlevler. Çünkü dil uygulama sistemleri
işletim sistemi tesislerinin çoğuna ihtiyaç duyarlar, işletim sistemi ile arayüz oluştururlar.
doğrudan işlemciden ziyade sistem (makine dilinde).
İşletim sistemi ve dil uygulamaları,
bir bilgisayarın makine dili arayüzü. Bu katmanlar şu şekilde düşünülebilir:
sanal bilgisayarlar, kullanıcıya daha yüksek seviyelerde arayüzler sağlar. Sınav için-
ple, bir işletim sistemi ve bir C derleyicisi sanal bir C bilgisayarı sağlar. İle
diğer derleyiciler, bir makine başka türde sanal bilgisayarlar olabilir. Çoğu
bilgisayar sistemleri birkaç farklı sanal bilgisayar sağlar. Kullanıcı programları
sanal bilgisayar katmanının üstünde başka bir katman oluşturun. katmanlı
bir bilgisayarın görünümü Şekil 1.2'de gösterilmektedir.
İlk üst düzey programlama dilinin uygulama sistemleri
1950'lerin sonlarında inşa edilen göstergeler, en karmaşık yazılımlar arasındaydı.
o zamanın sistemleri 1960'larda, yoğun araştırma çalışmaları yapıldı.
Bu üst düzey dili oluşturma sürecini anlamak ve resmileştirmek
uygulamalar. Bu çabaların en büyük başarısı, senkronizasyon alanında oldu.
vergi analizi, öncelikle uygulama sürecinin bu kısmı bir
otomata teorisi ve biçimsel dil teorisinin bölümlerinin uygulanması
o zaman iyi anlaşıldı
1.7.1 Derleme
Programlama dilleri, üç genel yöntemden herhangi biri ile uygulanabilir.
Bir uçta, programlar makine diline çevrilebilir.
doğrudan bilgisayarda yürütülebilir. Bu yönteme derleyici denir

Sayfa 46
1.7 Uygulama Yöntemleri 25
uygulama ve çok hızlı program yürütme avantajına sahiptir, bir kez
çeviri süreci tamamlandı. Lan'ın çoğu üretim uygulaması
C, COBOL, C++ ve Ada gibi göstergeler derleyicilere aittir.
Bir derleyicinin çevirdiği dile kaynak dil denir . bu
derleme ve program yürütme süreci birkaç aşamada gerçekleşir,
en önemlileri Şekil 1.3'te gösterilmiştir.
Sözlüksel çözümleyici, kaynak programın karakterlerini sözlükte toplar.
cal birimleri. Bir programın sözcük birimleri tanımlayıcılar, özel sözcükler, operatörler,
ve noktalama işaretleri. Sözlüksel çözümleyici kaynaktaki yorumları yok sayar
program, çünkü derleyicinin onlar için bir faydası yok.
Sözdizimi çözümleyici, sözcük çözümleyiciden sözcük birimlerini alır ve
ayrıştırma ağaçları adı verilen hiyerarşik yapılar inşa ederler . Bu ayrıştırma ağaçları
programın sözdizimsel yapısını temsil eder. Çoğu durumda, gerçek ayrıştırma yok
ağaç yapısı inşa edilmiştir; bunun yerine, gerekli olacak bilgiler
inşa bir ağaç oluşturulur ve doğrudan kullanılır. Hem sözcük birimleri hem de ayrıştırma ağaçları
daha ayrıntılı olarak Bölüm 3'te tartışılmıştır. Sözcüksel analiz ve sözdizimi analizi veya ayrıştırma,
4. Bölümde tartışılmaktadır.
İşletme
sistem
emretmek
Tercüman
şema
Tercüman
C
derleyici
Gerçek
C
bilgisayar
Gerçek
Ada
bilgisayar
Ada
derleyici
. . .
. . .
montajcı
Gerçek
toplantı
dilim
bilgisayar
Java Sanal
makine
Java
derleyici
.AĞ
Yaygın
dilim
Çalışma süresi
VB.NET
derleyici
C#
derleyici
Gerçek
VB.NET
bilgisayar
sanal C#
bilgisayar
Çıplak
makine
makro talimat
Tercüman
İşletim sistemi
sanal Java
bilgisayar
Gerçek
şema
bilgisayar
Şekil 1.2
Katmanlı arayüzü
sanal bilgisayarlar,
tipik tarafından sağlanan
bilgisayar sistemi

Sayfa 47
26
1. Bölüm Ön Hazırlıklar
Kaynak
program
sözlüksel
analizör
Sözdizimi
analizör
Orta düzey
kod üreteci
ve anlamsal
analizör
optimizasyon
(isteğe bağlı)
sembol
tablo
kod
jeneratör
Bilgisayar
Sonuçlar
Giriş verileri
makine
dilim
Orta düzey
kod
Ağaçları ayrıştırmak
sözcük birimleri
Şekil 1.3
Derleme süreci
Ara kod üreteci, farklı bir alanda bir program üretir.
kaynak program ile nihai çıktı arasında orta düzeyde
derleyicinin yerine: makine dili programı. 4 Orta seviye diller
bazen montaj dillerine çok benziyor ve aslında bazen
gerçek derleme dilleri. Diğer durumlarda, ara kod bir düzeydedir.
4. Program ve kod kelimelerinin sıklıkla birbirinin yerine kullanıldığını unutmayın.

Sayfa 48
1.7 Uygulama Yöntemleri 27
Assembly dilinden biraz daha yüksek. Semantik analizör bir inte-
ara kod oluşturucunun gral kısmı. Anlamsal çözümleyici şunları kontrol eder:
sırasında tespit edilmesi imkansız değilse de zor olan tür hataları gibi hatalar
sözdizimi analizi.
Programları iyileştiren optimizasyon (genellikle orta
kod sürümü) daha küçük veya daha hızlı veya her ikisini birden yaparak, genellikle isteğe bağlı bir parçadır.
derleme. Aslında, bazı derleyiciler önemli bir şey yapamazlar.
optimizasyon. Bu tür derleyici, yürütme işleminin gerçekleştirildiği durumlarda kullanılır.
çevrilen programın hızı derlemeden çok daha az önemlidir
hız. Böyle bir duruma bir örnek, başlangıç ​​için bir bilgisayar laboratuvarıdır.
programcılar Çoğu ticari ve endüstriyel durumda, yürütme hızı
derleme hızından daha önemlidir, bu nedenle optimizasyon rutin olarak istenir.
Makine dilinde birçok türde optimizasyon yapmak zor olduğundan,
çoğu optimizasyon ara kodda yapılır.
Kod oluşturucu, optimize edilmiş ara kod sürümünü çevirir.
programı eşdeğer bir makine dili programına dönüştürün.
Sembol tablosu, derleme işlemi için bir veritabanı görevi görür. bu
sembol tablosunun birincil içeriği, tür ve nitelik bilgileridir.
programdaki her kullanıcı tanımlı adın. Bu bilgiler,
sembol tablosu sözlük ve sözdizimi çözümleyicileri tarafından kullanılır ve anlamsal analiz tarafından kullanılır.
analizör ve kod üreteci.
Daha önce belirtildiği gibi, bir iletişim tarafından üretilen makine dili
piller doğrudan donanım üzerinde yürütülebilir, neredeyse her zaman çalıştırılmalıdır
başka bir kodla birlikte. Çoğu kullanıcı programı ayrıca aşağıdakilerden programlar gerektirir:
isletim sistemi. Bunların en yaygınları arasında giriş programları vardır.
ve çıktı. Derleyici, gerektiğinde sistem programlarına çağrılar oluşturur.
kullanıcı programı tarafından ihtiyaç duyulur. Makine dili programlarından önce pro-
Bir derleyici tarafından oluşturulan, işletim sisteminden gerekli programlar çalıştırılabilir.
sistem bulunmalı ve kullanıcı programına bağlanmalıdır. bağlama işlemi
adreslerini yerleştirerek kullanıcı programını sistem programlarına bağlar.
sistem programlarının giriş noktaları, kullanıcı pro-
gram. Birlikte bazen denir kullanıcı ve sistem kodu yük modülü ,
veya yürütülebilir görüntü . Sistem programlarını toplama ve bağlama süreci
bunları kullanıcı programlarına bağlama ve yükleme olarak adlandırılır veya bazen sadece bağlantı-
ing . Bağlayıcı adı verilen bir sistem programı tarafından gerçekleştirilir .
Sistem programlarına ek olarak, kullanıcı programları genellikle
kitaplıklarda bulunan önceden derlenmiş kullanıcı programları. Yani bağlayıcı değil
sadece belirli bir programı sistem programlarına bağlar, aynı zamanda onu diğer programlara da bağlayabilir.
kullanıcı programları
Bir bilgisayarın belleği ile işlemleri arasındaki bağlantının hızı.
sor genellikle bilgisayarın hızını belirler, çünkü talimatlar genellikle
yürütülmek üzere işlemciye taşınabileceklerinden daha hızlı yürütülebilirler.
Bu bağlantıya von Neumann darboğazı denir ; bu birincil
von Neumann mimarisi bilgisayarların hızında sınırlayıcı faktör. Von
Neumann darboğazı, araştırmanın temel motivasyonlarından biri olmuştur.
ve paralel bilgisayarların geliştirilmesi.

Sayfa 49
28
1. Bölüm Ön Hazırlıklar
1.7.2 Saf Yorum
Saf yorum, uygulamanın karşı ucunda (derlemeden) yatar.
yöntem yöntemleri. Bu yaklaşımla programlar başka bir program tarafından yorumlanır.
tercüman denir, ne olursa olsun tercümesi yoktur. tercüman programı
getirme-yürütme döngüsü ile ilgilenen bir makinenin yazılım simülasyonu olarak işlev görür.
makine yönergeleri yerine üst düzey dil programı ifadeleri. Bu
yazılım simülasyonu açıkça dil için sanal bir makine sağlar.
Saf yorumlama, aşağıdakilerin kolay uygulanmasına izin verme avantajına sahiptir.
birçok kaynak düzeyinde hata ayıklama işlemi, çünkü tüm çalışma zamanı hata mesajları
kaynak düzeyindeki birimlere başvurabilir. Örneğin, bir dizi indeksinin dışarıda olduğu tespit edilirse
aralığı, hata mesajı kaynak satırını ve adını kolayca gösterebilir
diziden. Öte yandan, bu yöntemin ciddi bir dezavantajı vardır.
yürütme, derlenmiş sistemlerden 10 ila 100 kat daha yavaştır. Birincil
bu yavaşlığın kaynağı, üst düzey dil ifadelerinin kodunun çözülmesidir.
makine dili talimatlarından çok daha karmaşıktır (ancak
eşdeğer makine kodundaki talimatlardan daha az ifade olabilir).
Ayrıca, bir ifade kaç kez çalıştırılırsa çalıştırılsın,
her seferinde kodu çözülür. Bu nedenle, bağlantı yerine deyim kod çözme
işlemci ve bellek arasındaki ilişki, saf bir yorumlayıcının darboğazıdır.
Saf yorumlamanın bir başka dezavantajı, genellikle daha fazlasını gerektirmesidir.
uzay. Kaynak programa ek olarak, sırasında sembol tablosu mevcut olmalıdır.
tercüme. Ayrıca, kaynak program tasarlanmış bir biçimde saklanabilir.
minimum boyut sağlamak yerine kolay erişim ve değişiklik için.
1960'ların bazı basit erken dilleri (APL, SNOBOL ve
LISP) tamamen yorumlandı, 1980'lerde yaklaşım nadiren kullanıldı.
üst düzey diller. Ancak son yıllarda saf yorum
JavaScript gibi bazı Web komut dosyası dilleriyle önemli bir geri dönüş
ve şu anda yaygın olarak kullanılan PHP. Saf yorumlama süreci,
Şekil 1.4'te gösterilmiştir.
Kaynak
program
Tercüman
Sonuçlar
Giriş verileri
Şekil 1.4
saf yorum

Sayfa 50
1.7 Uygulama Yöntemleri 29
1.7.3 Hibrit Uygulama Sistemleri
Bazı dil uygulama sistemleri, derleyiciler arasında bir uzlaşmadır.
ve saf tercümanlar; üst düzey dil programlarını inter-
kolay yorumlamaya izin verecek şekilde tasarlanmış arabulucu bir dil. Bu yöntem daha hızlı
kaynak dil ifadelerinin kodu çözüldüğü için saf yorumlamadan daha
sadece bir kere. Bu tür uygulamalara hibrit uygulama sistemleri denir .
Bir hibrit uygulama sisteminde kullanılan süreç şurada gösterilmiştir:
Şekil 1.5. Ara dil kodunu makineye çevirmek yerine
kodu, sadece ara kodu yorumlar.
Kaynak
program
Tercüman
Sonuçlar
Giriş verileri
sözlüksel
analizör
Sözdizimi
analizör
Orta düzey
kod üreteci
Ağaçları ayrıştırmak
sözcük birimleri
Orta düzey
kod
Şekil 1.5
Hibrit uygulama
sistem

Sayfa 51
30
1. Bölüm Ön Hazırlıklar
Perl, hibrit bir sistemle uygulanmaktadır. Perl programları kısmen
hataları yorumlamadan önce tespit etmek ve yorumlayıcıyı basitleştirmek için yığılmış.
Java'nın ilk uygulamalarının tümü hibritti. Onun ara formu,
bayt kodu adı verilen, bayt kodu olan herhangi bir makineye taşınabilirlik sağlar
yorumlayıcı ve ilişkili bir çalışma zamanı sistemi. Bunlara birlikte denir
Java Sanal Makinesi. Artık Java bayt kodunu şu dile çeviren sistemler var:
Daha hızlı yürütme için makine kodu.
Just-in-Time (JIT) uygulama sistemi başlangıçta programları çevirir
ara bir dile. Ardından, yürütme sırasında ara derler
dil yöntemleri, çağrıldıklarında makine koduna dönüştürülür. makine kodu
sürüm sonraki aramalar için saklanır. JIT sistemleri artık Java için yaygın olarak kullanılmaktadır.
programlar. Ayrıca, .NET dillerinin tümü bir JIT sistemi ile uygulanmaktadır.
Bazen bir uygulayıcı hem derlenmiş hem de yorumlanmış
Bir dil için uygulamalar. Bu durumlarda, tercüman geliştirmek için kullanılır.
ve hata ayıklama programları. Ardından, (nispeten) hatasız bir duruma ulaşıldıktan sonra,
programlar, yürütme hızlarını artırmak için derlenir.
1.7.4 Önişlemciler
Bir önişlemci hemen önce bir programı işleyen bir programdır
program derlenir. Önişlemci talimatları programlara gömülüdür.
Önişlemci aslında bir makro genişleticidir. Önişlemci talimatları
genellikle başka bir dosyadaki kodun dahil edileceğini belirtmek için kullanılır.
Örneğin, C önişlemci talimatı
#include "myLib.h"
önişlemcinin myLib.h içeriğini şu adresteki programa kopyalamasına neden olur .
#include öğesinin konumu .
Diğer önişlemci komutları, temsil edilecek sembolleri tanımlamak için kullanılır.
ifade. Örneğin, biri kullanabilir
#define max(A, B) ((A) > (B) ? (A) : (B))
verilen iki ifadenin en büyüğünü belirlemek için. Örneğin, ifade
x = maks(2 * y, z / 1.73);
önişlemci tarafından genişletilecek
x = ((2 * y) > (z / 1.73) ? (2 * y) : (z / 1.73);
Bunun, ifade yan etkilerinin neden olabileceği durumlardan biri olduğuna dikkat edin.
sorun. Örneğin, max makrosuna verilen ifadelerden herhangi biri
yan etkiler— z++ gibi— bir soruna neden olabilir. Çünkü ikisinden biri
ifade parametreleri iki kez değerlendirilir, bu z'nin artmasına neden olabilir.
makro genişletme tarafından üretilen kod tarafından iki kez belirtilir.

Sayfa 52
özet 31
1.8 Programlama Ortamları
Bir programlama ortamı, yazılımların geliştirilmesinde kullanılan araçların toplamıdır.
yazılım. Bu koleksiyon yalnızca bir dosya sisteminden, bir metin düzenleyiciden, bir bağlayıcıdan ve
bir derleyici. Veya her biri erişilen geniş bir entegre araç koleksiyonu içerebilir.
tek tip bir kullanıcı arayüzü aracılığıyla. İkinci durumda, geliştirme ve bakım
yazılım nance büyük ölçüde geliştirilmiştir. Bu nedenle, bir programın özellikleri-
ming dili, yazılım geliştirme yeteneğinin tek ölçüsü değildir.
bir sistem. Şimdi birkaç programlama ortamını kısaca açıklıyoruz.
UNIX, önce ortada dağıtılan daha eski bir programlama ortamıdır.
1970'ler, taşınabilir bir çoklu programlama işletim sistemi etrafında inşa edildi. Bir sağlar
yazılım üretimi ve bakımı için çok çeşitli güçlü destek araçları
çeşitli diller. Geçmişte UNIX'te olmayan en önemli özellik
araçları arasında tek tip bir arayüzdü. Bu öğrenmeyi zorlaştırdı ve
kullanmak. Ancak, UNIX artık genellikle bir grafik kullanıcı arabirimi aracılığıyla kullanılmaktadır.
(GUI) UNIX'in üzerinde çalışır. UNIX GUI'lerine örnek olarak Solaris Com-
mon Masaüstü Ortamı (CDE), GNOME ve KDE. Bu GUI'ler,
UNIX arabirimi, Windows ve Macintosh sistemlerine benzer görünür.
Borland JBuilder, etkileşim sağlayan bir programlama ortamıdır.
Java geliştirme için rendelenmiş derleyici, düzenleyici, hata ayıklayıcı ve dosya sistemi, burada
dördüne de grafiksel bir arayüz üzerinden erişilir. JBuilder karmaşık ve
Java yazılımı oluşturmak için güçlü bir sistem.
Microsoft Visual Studio .NET, evrimde nispeten yeni bir adımdır
yazılım geliştirme ortamları. Bu büyük ve ayrıntılı bir koleksiyon
tümü pencereli bir arayüz aracılığıyla kullanılan yazılım geliştirme araçları. Bu
sistem, beş .NET dilinden herhangi birinde yazılım geliştirmek için kullanılabilir:
C#, Visual BASIC .NET, JScript (Microsoft'un JavaScript sürümü), F# (bir işlev-
ulusal dil) ve C++/CLI.
NetBeans, öncelikle Java için kullanılan bir geliştirme ortamıdır.
uygulama geliştirmenin yanı sıra JavaScript, Ruby ve PHP'yi de destekler. Her ikisi de
Visual Studio ve NetBeans, geliştirme ortamlarından daha fazlasıdır;
aynı zamanda çerçevelerdir, bu da aslında çerçevenin ortak kısımlarını sağladıkları anlamına gelir.
uygulamanın kodu.
ÖZET
Programlama dillerinin incelenmesi bazı önemli nedenlerden dolayı değerlidir:
program yazmada farklı yapıları kullanma kapasitemizi arttırır,
projeler için dilleri daha akıllıca seçmemizi ve öğrenmeyi yeni hale getirmemizi
diller daha kolay.
Bilgisayarlar çok çeşitli problem çözme alanlarında kullanılmaktadır. bu
Belirli bir programlama dilinin tasarımı ve değerlendirilmesi son derece bağımlıdır.
kullanılacağı alan üzerinde çentik.

Sayfa 53
32
1. Bölüm Ön Hazırlıklar
Dilleri değerlendirmek için en önemli kriterler arasında okunabilirlik,
yazılabilirlik, güvenilirlik ve toplam maliyet. Bunlar bizim dayandığımız temel olacak
kalan kısımda tartışılan çeşitli dil özelliklerini inceleyin ve yargılayın
kitabın.
Dil tasarımı üzerindeki en büyük etkiler makine mimarisi olmuştur.
ve yazılım tasarım metodolojileri.
Bir programlama dili tasarlamak öncelikle bir mühendislik başarısıdır.
özellikler, yapılar ve özellikler arasında uzun bir değiş tokuş listesi yapılması gereken
yetenekler.
Programlama dillerini uygulamanın başlıca yöntemleri derlemedir.
tion, saf yorumlama ve hibrit uygulama.
Programlama ortamları, yazılımın önemli parçaları haline geldi
dilin bileşenlerden sadece biri olduğu geliştirme sistemleri.
İNCELEME SORULARI
1. Bir programcının dilde biraz geçmişe sahip olması neden yararlıdır?
tasarım, aslında hiçbir zaman bir programlama tasarlamasa bile
dilim?
2. Programlama dili özellikleri bilgisi, kullanıcıya nasıl fayda sağlayabilir?
tüm bilgisayar topluluğu?
3. Hangi programlama dili bilimsel hesaplamaya egemen oldu?
son 50 yıl?
4. Hangi programlama dili iş uygulamalarına üstün geldi?
son 50 yıl?
5. Hangi programlama dili yapay zekaya egemen oldu?
son 50 yıl?
6. UNIX'in çoğu hangi dilde yazılmıştır?
7. Bir dilde çok fazla özelliğe sahip olmanın dezavantajı nedir?
8. Kullanıcı tanımlı operatör aşırı yüklemesi, bir bilgisayarın okunabilirliğine nasıl zarar verebilir?
program?
9. C'nin tasarımında ortogonallik eksikliğinin bir örneği nedir?
10. Ortogonalliği birincil tasarım kriteri olarak hangi dil kullandı?
11. Daha karmaşık yapı oluşturmak için hangi ilkel kontrol ifadesi kullanılır?
Onlardan yoksun dillerde kontrol ifadeleri?
12. Bir programlama dilinin hangi yapısı süreç sağlar?
soyutlama?
13. Bir programın güvenilir olması ne anlama gelir?
14. Bir alt programın parametrelerinin tip kontrolü neden önemlidir?
15. Takma ad nedir?

Sayfa 54
Problem Seti 33
16. İstisna işleme nedir?
17. Okunabilirlik yazılabilirlik için neden önemlidir?
18. Belirli bir dil için derleyicilerin tasarımıyla ilgili maliyeti nasıldır?
o dil?
19. Programlama dili üzerindeki en güçlü etkiler nelerdi?
son 50 yılda tasarım?
20. Programlama dilleri kategorisinin adı nedir?
yapı von Neumann bilgisayar mimarisi tarafından belirlenir?
21. Hangi iki programlama dili eksikliği keşfedildi?
1970'lerde yazılım geliştirme araştırmalarının sonucu mu?
22. Nesne yönelimli bir programın üç temel özelliği nelerdir?
ming dili?
23. Dilin üç temel özelliğini destekleyen ilk dil hangisidir?
nesne yönelimli programlama?
24. Doğrudan geçerli olan iki dil tasarım kriterine örnek nedir?
birbiriyle çatışıyor mu?
25. Bir programlamayı uygulamanın üç genel yöntemi nelerdir?
dilim?
26. Hangisi daha hızlı program yürütme üretir, bir derleyici veya saf
Tercüman?
27. Bir derleyicide sembol tablosunun rolü nedir?
28. Bağlayıcı ne yapar?
29. Von Neumann darboğazı neden önemlidir?
30. Bir dili saf bir dille uygulamanın avantajları nelerdir?
Tercüman?
PROBLEM SETİ
1. Soyut düşünce kapasitemizin bizim düşüncelerimizden etkilendiğine inanıyor musunuz?
dil becerileri? Fikrinizi destekleyin.
2. Bildiğiniz belirli programlama dillerinin bazı özellikleri nelerdir?
kimin gerekçeleri senin için bir gizem?
3. Herkes için tek bir dil fikri için hangi argümanları sunabilirsiniz?
programlama alanları?
4. Tek bir dil fikrine karşı hangi argümanları ileri sürebilirsiniz?
tüm programlama alanları?
5. Dillerin değerlendirilebileceği başka bir kriteri adlandırın ve açıklayın
(bu bölümde tartışılanlara ek olarak).

Sayfa 55
34
1. Bölüm Ön Hazırlıklar
6. Sizce hangi yaygın programlama dili ifadesi
okunabilirlik için en zararlı?
7. Java, tüm bileşik ifadelerin sonunu işaretlemek için bir sağ ayraç kullanır.
Bu tasarımın lehine ve aleyhine olan argümanlar nelerdir?
8. Birçok dilde büyük ve küçük harfler arasında ayrım yapılır.
kullanıcı tanımlı adlar. Bu tasarım kararının artıları ve eksileri nelerdir?
9. Bir programlama dilinin maliyetinin farklı yönlerini açıklayın.
10. Her ne kadar verimli programlar yazmak için argümanlar nelerdir?
donanım nispeten ucuz mu?
11. Bazılarında verimlilik ve güvenlik arasındaki bazı tasarım ödünleşimlerini tanımlayın.
bildiğin dil.
12. Size göre mükemmel bir programlama lan-
guaj dahil?
13. Öğrendiğiniz ilk üst düzey programlama dili,
saf bir yorumlayıcı, hibrit bir uygulama sistemi veya bir
derleyici? (Bunu araştırmanız gerekebilir.)
14. Bazı programlama ortamlarının avantaj ve dezavantajlarını tanımlayın.
kullandığın urun.
15. Basit değişkenler için tip bildirim deyimleri okumayı nasıl etkiler?
bazı dillerin gerektirmediği düşünüldüğünde, bir dilin yeteneği
onlara?
16. Bildiğiniz bazı programlama dillerinin değerlendirmesini aşağıdaki
Bu bölümde açıklanan kriterler.
17. Bazı programlama dilleri, örneğin Pascal,
ifadeleri ayırmak için noktalı virgül, Java ise durumu sonlandırmak için kullanır.
mentler. Sizce bunlardan hangisi en doğal ve en az olasıdır?
sözdizimi hatalarına neden olmak için? Cevabınızı destekleyin.
18. Birçok çağdaş dil iki tür yoruma izin verir:
her iki uçta da hangi sınırlayıcıların kullanıldığı (çok satırlı yorumlar) ve
bir sınırlayıcının yorumun yalnızca başlangıcını işaretlediği bir (bir-
satır yorumları). Her birinin avantaj ve dezavantajlarını tartışın
Bunlar kriterlerimize göre.

Sayfa 56
35
2.1 Zuse'nin Plankalkül'ü
2.2 Sözde kodlar
2.3 IBM 704 ve Fortran
2.4 Fonksiyonel Programlama: LISP
2.5 Gelişmişliğe Doğru İlk Adım: ALGOL 60
2.6 İş Kayıtlarının Bilgisayarlaştırılması: COBOL
2.7 Devre Paylaşımın Başlangıcı: TEMEL
2.8 Herkes İçin Her Şey: PL/I
2.9 İki Erken Dinamik Dil: APL ve SNOBOL
2.10 Veri Soyutlamanın Başlangıcı: SIMULA 67
2.11 Ortogonal Tasarım: ALGOL 68
2.12 ALGOL'lerin Bazı Erken Torunları
2.13 Mantığa Dayalı Programlama: Prolog
2.14 Tarihin En Büyük Tasarım Çabası: Ada
2.15 Nesne Yönelimli Programlama: Smalltalk
2.16 Zorunlu ve Nesne Yönelimli Özellikleri Birleştirme: C++
2.17 Zorunlu Tabanlı Nesne Yönelimli Bir Dil: Java
2.18 Komut Dosyası Dilleri
2.19 Amiral Gemisi .NET Dili: C#
2.20 Hibrit Dilleri İşaretleme/Programlama
2
Binbaşının Evrimi
Programlama dilleri

Sayfa 57
36
Bölüm 2 Başlıca Programlama Dillerinin Evrimi
Bu bölümde, bir programlama dili koleksiyonunun geliştirilmesi anlatılmaktadır.
göstergeler. Her birinin tasarlandığı ve odaklandığı ortamı keşfeder.
dilin katkıları ve gelişimi için motivasyon üzerine.
Genel dil açıklamaları dahil değildir; daha ziyade, sadece bazılarını tartışıyoruz
her dilin sunduğu yeni özellikler. Özellikle ilgi çekici olan özellikler
sonraki dilleri veya bilgisayar bilimi alanını en çok etkileyen.
Bu bölüm, herhangi bir dil özelliği veya
kavram; o da sonraki bölümlere kaldı. Özelliklerin kısa, resmi olmayan açıklamaları
bu dillerin geliştirilmesi yoluyla yürüyüşümüz için yeterlidir.
Bu bölüm çok çeşitli dilleri ve dil kavramlarını tartışır.
pek çok okuyucuya tanıdık gelmeyecektir. Bu konular sadece ayrıntılı olarak tartışılmaktadır.
sonraki bölümler. Bunu rahatsız edici bulanlar bu bölümü okumayı ertelemeyi tercih edebilirler.
kitabın geri kalanı çalışılana kadar.
Burada hangi dillerin tartışılacağı konusundaki seçim özneldi ve bazıları
okuyucular, favorilerinden bir veya daha fazlasının yokluğunu üzülerek fark edeceklerdir. Ancak,
Bu tarihsel kapsamı makul bir boyutta tutmak için, dışarıda bırakmak gerekiyordu.
bazılarının çok saygı duyduğu bazı diller. Seçimler bizim tahminimize dayanıyordu.
dil gelişimi ve bilgisayar dünyası için her dilin önemi
tüm. Ayrıca atıfta bulunulan diğer bazı dillerin kısa tartışmalarını da dahil ediyoruz.
daha sonra kitapta.
Bu bölümün organizasyonu aşağıdaki gibidir: Dillerin ilk sürümleri
genellikle kronolojik sıraya göre tartışılır. Ancak, lan-
göstergeler sonraki bölümlerde değil, ilk sürümleriyle birlikte görünür. Örneğin,
Fortran 2003, Fortran I (1956) ile ilgili bölümde tartışılmaktadır. Ayrıca, bazı durumlarda,
kendine ait bir dille ilişkili ikincil öneme sahip diller
bölümü o bölümde görünür.
Bu bölüm, her biri ayrı ayrı 14 tam örnek programın listesini içerir.
farklı dil. Bu programlar bu bölümde anlatılmamıştır; onlar kastediliyor
sadece bu dillerdeki programların görünümünü göstermek için. okuyucular tanıdık
ortak zorunlu dillerden herhangi biriyle okuyabilmeli ve anlayabilmelidir
LISP, COBOL ve Smalltalk dışındaki bu programlardaki kodun çoğu.
(LISP örneğine benzer bir Şema işlevi Bölüm 15'te tartışılmaktadır.) Aynı
problem Fortran, ALGOL 60, PL/I, BASIC, Pascal, C, Perl, Ada, Java,
JavaScript ve C# programları. Bu konudaki çağdaş dillerin çoğunun
list dinamik dizileri destekler, ancak örnek problemin basitliği nedeniyle,
örnek programlarda kullanmadık. Ayrıca Fortran 95 programında
döngülerin kullanımını tamamen önleyebilecek özellikleri kullanmaktan kaçındı,
programı basit ve okunabilir tutmak için ve kısmen de sadece temel bilgileri göstermek için
Dilin döngü yapısı.
Şekil 2.1, yukarıda tartışılan yüksek seviyeli dillerin soyağacının bir çizelgesidir.
bu bölüm.

Sayfa 58
Bölüm 2 Ana Programlama Dillerinin Evrimi 37
1957
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
00
01
02
03
04
05
06
07
08
09
10
11
ALGOL 58
ALGOL 60
ALGOL W
paskal
TEMEL
Oberon
MODÜL-3
Eyfel
ANSI C (C89)
90
95
77
Fortran IV
Fortran II
Fortran I
Visual Basic
QuickBASIC
CPL
BCPL
C
B
PL/I
COBOL
LISP
şema
AKIŞ-MATIK
C++
APL
ORTAK LISP
MODÜL-2
SNOBOL
İKON
SIMULA I
SIMULA 67
ALGOL 68
Ada 83
küçük konuşma 80
Ada 95
Ada 2005
Lua
Java
Javascript
yakut
Yakut 1.8
Yakut 1.9
Prolog
Java 5.0
Java 6.0
Java 7.0
Miranda
Haskell
piton
Python 2.0
Python 3.0
makine öğrenimi
Perl
PHP
C99
C#
C# 2.0
C# 3.0
C# 4.0
Visual Basic.NET
awk
2003
2008
Şekil 2.1
Ortak üst düzey programlama dillerinin soykütüğü

Sayfa 59
38
Bölüm 2 Başlıca Programlama Dillerinin Evrimi
2.1 Zuse'nin Plankalkül'ü
Bu bölümde tartışılan ilk programlama dili oldukça sıra dışıdır.
birkaç açıdan. Bir kere, hiç uygulanmadı. Üstelik,
1945'te geliştirilmiş olmasına rağmen, açıklaması 1972'ye kadar yayınlanmadı.
Dile çok az insan aşina olduğu için, dilin bazı yetenekleri
geliştirilmesinden 15 yıl sonrasına kadar diğer dillerde görünmedi.
2.1.1 Tarihsel Arkaplan
1936 ve 1945 yılları arasında Alman bilim adamı Konrad Zuse (“Tsoo-
zuh”) elektrome- den bir dizi karmaşık ve karmaşık bilgisayar inşa etti.
mekanik röleler. 1945'in başlarında, Müttefik bombalamaları biri hariç hepsini yok etmişti.
en yeni modeller olan Z4, bu yüzden uzak bir Bavyera köyü olan Hinterstein'a taşındı.
ve araştırma grubu üyeleri kendi yollarına gittiler.
Zuse tek başına çalışarak bir dil geliştirme çabasına girişti.
1943'te profesyonel olarak başladığı bir proje olan Z4 için hesaplamaları ifade ederek
Doktora için pozal tez. Bu dile Plankalkül adını verdi.
program hesabı anlamına gelir . 1945 tarihli ancak yayınlanmamış uzun bir el yazmasında
1972 yılına kadar (Zuse, 1972), Zuse Plankalkül'ü tanımlamış ve algoritmalar yazmıştır.
Çeşitli sorunları çözmek için dil.
2.1.2 Dile Genel Bakış
Plankalkül, en gelişmiş özelliklerinden bazıları ile dikkat çekici bir şekilde tamamlandı.
veri yapıları alanında. Plankalkül'deki en basit veri türü,
tek bit. Tamsayı ve kayan noktalı sayısal türleri, bitten oluşturulmuştur.
tip. Kayan nokta türü, iki tamamlayıcı notasyonu ve “gizli-
den bit” şeması şu anda en önemli bitin saklanmasını önlemek için kullanılmaktadır.
kayan noktalı bir değerin normalleştirilmiş kesir kısmı.
Alışılmış skaler tiplere ek olarak, Plankalkül diziler ve kayıtlar içeriyordu.
( C tabanlı dillerde yapılar olarak adlandırılır ). Kayıtlar iç içe geçmiş içerebilir
kayıtlar.
Dilin açık bir girişi olmamasına rağmen, yinelemeli bir durum içeriyordu.
Ada benzer ment için . Ayrıca bir üst simgeyle birlikte Fin komutuna sahipti.
belirli sayıda yineleme döngüsü yuvalamasından veya
yeni bir yineleme döngüsünün başlangıcı. Plankalkül'de bir seçim ifadesi yer aldı,
ama başka bir maddeye izin vermedi .
Zuse'nin programlarının en ilginç özelliklerinden biri,
arasındaki mevcut ilişkileri gösteren matematiksel ifadelerin
gram değişkenleri. Bu ifadeler, yürütme sırasında neyin doğru olacağını belirtti.
kodda göründükleri noktalarda. Bunlar çok benzer
Java'nın iddiaları ve içinde tartışılan aksiyomatik anlambilimdeki iddialar
Bölüm 3.

Sayfa 60
Zuse'nin el yazması, herhangi bir programdan çok daha karmaşık programlar içeriyordu.
1945'ten önce yazılmış. Sayı dizilerini sıralamak için programlar; Ölçek
belirli bir grafiğin bağlanabilirliği; tamsayı ve kayan nokta işlemlerini yürütmek
karekök dahil olmak üzere; ve mantık formülleri üzerinde sözdizimi analizi yapın.
altı farklı öncelik düzeyinde parantezler ve operatörler vardı. Belki
en dikkat çekici olanı, satranç oynamak için 49 sayfalık algoritmalarıydı.
ki o bir uzman değildi.
Eğer bir bilgisayar bilimcisi Zuse'nin Plankalkül tarifini
1950'lerin başında, dilin gelişimini engelleyen tek yönü
tanımlandığı gibi uygulama gösterim olurdu. Her bir ifade bağ-
iki veya üç kod satırından oluşur. İlk satır en çok devlet gibiydi-
mevcut dillerin özellikleri. İsteğe bağlı olan ikinci satır şunları içeriyordu:
ilk satırdaki dizi referanslarının aboneleri. Aynı yöntem
gösteren abonelikler Charles Babbage tarafından Ana-
On dokuzuncu yüzyılın ortalarında litik Motor. Her birinin son satırı
Plankalkül deyiminde belirtilen değişkenlerin tip adlarını içeriyordu.
ilk satır. Bu gösterim ilk görüldüğünde oldukça korkutucu.
değerini atayan aşağıdaki örnek atama ifadesi
A[4] +1 ila A[5] ifadesi bu gösterimi gösterir. Satır etiketli V olan
indisler içindir ve S etiketli satır veri türleri içindir. Bu örnekte, 1.n
n bitlik bir tam sayı anlamına gelir :
| A + 1 => A
V | 4
5
S | 1.n 1.n
Sadece programlama dili tasarımının yönü hakkında spekülasyon yapabiliriz.
Zuse'nin çalışması 1945'te, hatta 1950'de geniş çapta biliniyor olsaydı, alınabilirdi.
O olsaydı çalışmasının nasıl farklı olabileceğini düşünmek de ilginçtir.
yerine diğer bilim adamlarının çevrelediği barışçıl bir ortamda yaptı.
Almanya'da 1945'te sanal izolasyonda.
2.2 Sözde kodlar
İlk olarak, sözde kod kelimesinin burada onunkinden farklı bir anlamda kullanıldığına dikkat edin .
çağdaş anlamı. Bu bölümde tartışılan dillere sözde dil diyoruz.
kodlar çünkü geliştirildikleri sırada adlandırıldılar ve
kullanıldı (1940'ların sonu ve 1950'lerin başı). Ancak, açıkça sözde değiller.
çağdaş anlamda kodlar.
1940'ların sonlarında ve 1950'lerin başlarında kullanıma sunulan bilgisayarlar
bugünkünden çok daha az kullanışlıydı. Yavaş, güvenilmez olmasının yanı sıra,
pahalı ve son derece küçük hafızalara sahip olan o zamanın makineleri
Destekleyici yazılımların olmaması nedeniyle programlanması zordu.
Üst düzey programlama dilleri ve hatta montaj dili yoktu.
Bu nedenle programlama, hem sıkıcı hem de zahmetli olan makine kodunda yapıldı.
2.2 Sözde kodlar 39

Sayfa 61
40
Bölüm 2 Başlıca Programlama Dillerinin Evrimi
hata eğilimli. Sorunları arasında, belirtmek için sayısal kodların kullanılması vardır.
Talimatlar. Örneğin, bir ADD komutu kod tarafından belirtilebilir.
14 tek bir harf bile olsa çağrışımsal bir metin adı yerine. Bu
programların okunmasını çok zorlaştırır. Daha ciddi bir sorun mutlak
adresleme, program değişikliğini sıkıcı ve hataya açık hale getirir. İçin
Örneğin, bellekte depolanmış bir makine dili programımız olduğunu varsayalım.
Böyle bir programdaki talimatların çoğu, program içindeki diğer konumlara atıfta bulunur.
program, genellikle verilere referans vermek veya şube talimatlarının hedeflerini belirtmek için
tion. Programdaki herhangi bir konuma komut ekleme
son, adreslere atıfta bulunan tüm talimatların doğruluğunu geçersiz kılar
ekleme noktasının ötesinde, çünkü bu adreslerin
yeni talimat için yer. Eklemeyi doğru yapmak için tüm talimatlar
eklemeyi takip eden adreslere atıfta bulunanlar bulunmalı ve değiştirilmelidir. A
benzer bir sorun bir talimatın silinmesiyle ortaya çıkar. Ancak bu durumda,
makine dilleri genellikle, değiştirilebilecek bir "işlem yok" talimatı içerir.
silinen talimatlar, böylece sorundan kaçınılır.
Bunlar, tüm makine dillerinde standart sorunlardır ve
montajcıları ve montaj dillerini icat etmek için birincil motivasyonlar. ek olarak
O zamanın çoğu programlama problemi sayısaldı ve gerekliydi.
izin vermek için kayan noktalı aritmetik işlemler ve bir tür indeksleme
dizilerin rahat kullanımı. Bununla birlikte, bu yeteneklerin hiçbiri dahil edilmedi.
1940'ların sonu ve 1950'lerin başındaki bilgisayarların mimarisi. Bu tanım-
bilimler doğal olarak biraz daha yüksek seviyeli dillerin gelişmesine yol açtı.
2.2.1 Kısa Kod
Kısa Kod adı verilen bu yeni dillerden ilki John tarafından geliştirilmiştir.
Mauchly, 1949'da ilk başarılardan biri olan BINAC bilgisayarı için-
tam depolanmış programlı elektronik bilgisayarlar. Kısa Kod daha sonra
Bir UNIVAC I bilgisayarı (Türkiye'de satılan ilk ticari elektronik bilgisayar
Birleşik Devletler) ve birkaç yıl boyunca pro-
bu makinelerin gramajı Orijinal Kısa Kod hakkında çok az şey bilinmesine rağmen
tam açıklaması hiçbir zaman yayınlanmadığından, bir programlama kılavuzu
UNIVAC I versiyonu için hayatta kaldı (Remington-Rand, 1952). güvenli
iki versiyonun çok benzer olduğunu varsayalım.
UNIVAC I'in belleğindeki kelimeler, 12 altı bit olarak gruplandırılmış 72 bitten oluşuyordu.
bayt. Kısa Kod, matematiksel ifadelerin kodlanmış versiyonlarından oluşuyordu.
değerlendirilmek üzereydi. Kodlar bayt çifti değerleri ve birçok denklemdi.
bir kelime ile kodlanabilir. Aşağıdaki işlem kodları dahil edildi:
01 - 06 abs değeri 1n (n+2)nd güç
02 ) 07 +
2n (n+2)nd kök
03 = 08 duraklama
4n ise <= n
04 / 09 (
58 baskı ve sekme

Sayfa 62
Değişkenler bayt çifti kodlarıyla isimlendirildi ve konum olarak kullanılacak yerler
sabitler. Örneğin, X0 ve Y0 değişkenler olabilir. İfade
X0 = KARE(ABS(Y0))
bir kelimede 00 X0 03 20 06 Y0 olarak kodlanır . İlk 00 kullanıldı
kelimeyi doldurmak için dolgu olarak. İlginç bir şekilde, çarpma kodu yoktu;
çarpma, iki işlenenin her birinin yanına yerleştirilmesiyle gösterildi.
diğer, cebirde olduğu gibi.
Kısa Kod makine koduna çevrilmedi; daha doğrusu uygulandı
saf bir tercüman ile. O zamanlar bu işleme otomatik program adı verildi.
ming. Programlama sürecini açıkça basitleştirdi, ancak bunun pahasına
uygulama vakti. Kısa Kod yorumlama yaklaşık 50 kat daha yavaştı
makine kodundan daha fazla.
2.2.2 Hız kodlaması
Başka yerlerde, genişleyen yorumlayıcı sistemler geliştiriliyordu.
kayan nokta işlemlerini içerecek makine dilleri. Hız kodlaması
John Backus tarafından IBM 701 için geliştirilen sistem böyle bir örnektir.
sistemi (Backus, 1954). Speedcoding yorumlayıcısı,
701'i sanal üç adresli kayan nokta hesaplayıcıya dönüştürün. Sistem dahil
kayan noktadaki dört aritmetik işlem için sözde komutlar
karekök, sinüs, yay tanjantı, üs gibi işlemlerin yanı sıra veriler,
ve logaritma. Koşullu ve koşulsuz dallar ve giriş/çıkış
dönüşümler de sanal mimarinin bir parçasıydı. hakkında bir fikir edinmek için
bu tür sistemlerin sınırlamaları, sonra kalan kullanılabilir belleğin
yorumlayıcıyı yüklemek sadece 700 kelimeydi ve ekleme talimatı
Yürütmek için 4.2 milisaniye. Öte yandan, Speedcoding şunları içeriyordu:
otomatik olarak artan adres kayıtlarının yeni özelliği. Bu tesis yaptı
1962'nin UNIVAC 1107 bilgisayarlarına kadar donanımda görünmüyordu.
gibi özellikler, matris çarpımı 12 Speedcoding talimatında yapılabilmektedir.
tion. Backus, programlanması iki hafta sürebilecek sorunların
makine kodu, Speedcoding kullanılarak birkaç saat içinde programlanabilir.
2.2.3 UNIVAC “Derleme” Sistemi
1951 ve 1953 yılları arasında, UNIVAC'ta Grace Hopper tarafından yönetilen bir ekip, bir
A-0, A-1 ve A-2 adlı bir dizi "derleme" sistemi,
makroların genişletilmesiyle aynı şekilde makine kodu alt programlarına kod
montaj diline dönüştürülür. Bu "derleyiciler" için sözde kod kaynağı hala
oldukça ilkel, ancak bu bile makine koduna göre büyük bir gelişmeydi
çünkü kaynak programları çok daha kısa hale getirdi. Wilkes (1952) bağımsız olarak
benzer bir süreç önerdi.
2.2 Sözde kodlar 41

Sayfa 63
42
Bölüm 2 Başlıca Programlama Dillerinin Evrimi
2.2.4 İlgili Çalışma
Programlama görevini kolaylaştırmanın diğer yolları yaklaşık olarak geliştiriliyordu.
Aynı zaman. Cambridge Üniversitesi'nde David J. Wheeler (1950) tarafından geliştirilen
en azından kısmen çözmek için yeniden yerleştirilebilir adres bloklarını kullanma yöntemi.
mutlak adresleme sorunu ve daha sonra Maurice V. Wilkes (ayrıca Cam-
köprüsü) birleştirebilecek bir montaj programı tasarlama fikrini genişletti.
seçilen alt rutinler ve depolama tahsisi (Wilkes ve diğerleri, 1951, 1957). Buydu
gerçekten de önemli ve temel bir ilerleme.
Birbirinden oldukça farklı olan Assembly dillerinden de bahsetmeliyiz.
tartışılan sözde kodlardan, 1950'lerin başında gelişti. Ancak, onlar
yüksek seviyeli dillerin tasarımı üzerinde çok az etkisi oldu.
2.3 IBM 704 ve Fortran
Bilgisayar alanındaki en büyük ilerlemelerden biri kesinlikle
IBM 704'ün 1954'te piyasaya sürülmesi, büyük ölçüde yetenekleri nedeniyle
Fortran'ın gelişmesini sağladı. Olmasaydı, şu iddia edilebilirdi:
704 ve Fortran ile IBM, bundan kısa bir süre sonra başka bir şey olacaktı.
benzer bir bilgisayar ve ilgili üst düzey dil ile organizasyon. Nasıl-
IBM, hem öngörü hem de üstlenecek kaynaklara sahip ilk şirketti.
bu gelişmeler.
2.3.1 Tarihsel Arkaplan
Yorumlayıcı sistemlerin yavaşlığının başlıca nedenlerinden biri,
1940'ların sonundan 1950'lerin ortalarına kadar geçen süre içinde kayan nokta eksikliği vardı.
mevcut bilgisayarlarda donanım. Tüm kayan nokta işlemleri
yazılımda simüle edildi, çok zaman alan bir süreç. Çünkü çok fazla pro-
yazılım kayan nokta işlemede harcanan zaman,
yorumlama ve indeksleme simülasyonu nispeten önemsizdi. Olarak
kayan noktanın yazılım tarafından yapılması gerektiği sürece, yorumlama kabul edilebilirdi.
mümkün masraf. Ancak, o zamanın birçok programcısı asla yorum kullanmadı.
Elle kodlanmış makinenin (veya montajın) verimliliğini tercih eden sistemler
dilim. IBM 704 sisteminin hem indeksleme hem de indeksleme ile duyurulması
donanımdaki kayan noktalı komutlar, yorumlamanın sonunun habercisiydi
çağ, en azından bilimsel hesaplama için. Kayan nokta sabitinin dahil edilmesi
ware, yorumlama maliyeti için saklanma yerini kaldırdı.
Fortran genellikle ilk derlenen yüksek-
seviyeli dil, ilkini uygulamak için kimin krediyi hak ettiği sorusu
böyle bir dil biraz açıktır. Knuth ve Pardo (1977)
Alick E. Glennie, Manchester Mark I com için Autocode derleyicisi için
bilgisayar. Glennie derleyiciyi Fort Halstead, Royal Armaments'ta geliştirdi.
İngiltere'de Araştırma Kuruluşu. Derleyici Eylül ayına kadar faaliyete geçmişti.
Temmuz 1952. Ancak, John Backus'a göre (Wexelblat, 1981, s. 26),

Sayfa 64
Glennie'nin Otomatik Kodu o kadar düşük seviyeli ve makine odaklıydı ki,
derlenmiş bir sistem olarak kabul edilir. Backus, krediyi Laning ve Zierler'e veriyor
Massachusetts Teknoloji Enstitüsü'nde.
Laning ve Zierler sistemi (Laning ve Zierler, 1954) ilk
cebirsel çeviri sistemi uygulanacaktır. Cebirsel derken bunu kastediyoruz.
çevrilmiş aritmetik ifadeler, ayrı ayrı kodlanmış alt programlar kullanılarak
pute transandantal fonksiyonlar (örneğin, sinüs ve logaritma) ve dahil edilen diziler.
Sistem, deneysel olarak MIT Whirlwind bilgisayarında uygulandı.
zihinsel prototip formu, 1952 yazında ve daha kullanışlı bir biçimde
Mayıs 1953. Çevirmen, her formülü kodlamak için bir alt program çağrısı oluşturdu,
veya ifade, programda. Kaynak dilin okunması kolaydı ve
dahil edilen yalnızca gerçek makine talimatları dallanma içindi. Buna rağmen
iş Fortran'daki çalışmalardan önce geldi, asla MIT'den kaçmadı.
Bu daha önceki çalışmalara rağmen, yaygın olarak kabul edilen ilk derlenmiş yüksek
Düzey dili Fortran'dı. Aşağıdaki alt bölümlerde bu önemli
gelişim.
2.3.2 Tasarım Süreci
704 sistemi Mayıs 1954'te duyurulmadan önce bile, bunun için planlar yapılmaya başlandı.
Fortran. Kasım 1954'te, John Backus ve IBM'deki grubu,
“The IBM Mathematical FORmula TRANslating System: IBM Mathematical FORmula TRANslating System:
FORTRAN” (IBM, 1954). Bu belge, For-
Uygulamadan önce Fortran 0 olarak adlandırdığımız tran. Ayrıca cesurca
Fortran'ın elle kodlanmış programların verimliliğini sağlayacağını ve
yorumlayıcı sözde kod sistemlerinin programlanmasının kolaylığı. Başka
iyimserlik patlaması, belge Fortran'ın kodlamayı ortadan kaldıracağını belirtti
hatalar ve hata ayıklama süreci. Bu önermeye dayanarak, ilk Fortran
derleyici küçük sözdizimi hatası denetimi içeriyordu.
Fortran'ın geliştirildiği ortam aşağıdaki gibidir: (1)
bilgisayarcıların küçük hafızaları vardı ve yavaştı ve nispeten güvenilmezdi; (2)
bilgisayarların birincil kullanımı bilimsel hesaplamalar içindi; (3) yoktu
bilgisayarları programlamak için mevcut verimli ve etkili yollar; ve (4) nedeniyle
programcıların maliyetine kıyasla bilgisayarların yüksek maliyeti,
oluşturulan nesne kodu, ilk Fortran derleyicilerinin birincil amacıydı.
Fortran'ın ilk sürümlerinin özellikleri doğrudan bundan kaynaklanmaktadır.
Çevre.
2.3.3 Fortran I Genel Bakış
Fortran 0, 2012 yılında başlayan uygulama döneminde değiştirildi.
Ocak 1955 ve Nisan 1957'de derleyicinin yayınlanmasına kadar devam etti.
Fortran I dediğimiz uygulamalı dil, ilk Fortran'da açıklanmıştır.
Ekim 1956'da yayınlanan Programcı Referans Kılavuzu (IBM, 1956). İçin-
tran giriş/çıkış biçimlendirmesini, altı karaktere kadar değişken adlarını dahil ettim
(Fortran 0'da sadece iki taneydi), kullanıcı tanımlı alt rutinler
2.3 IBM 704 ve Fortran 43

Sayfa 65
44
Bölüm 2 Başlıca Programlama Dillerinin Evrimi
Ayrı ayrı derlenemedi, If seçim ifadesi ve Do döngüsü
Beyan.
Fortran I'in tüm kontrol ifadeleri 704 talimatına dayanıyordu. Bu
704 tasarımcılarının kontrol ifadesi tasarımını dikte edip etmediği açık değil.
Fortran I veya Fortran I tasarımcıları bu talimatları önerdi mi?
704 tasarımcılara.
Fortran I dilinde veri yazma ifadesi yoktu. Değişkenler
isimleri I , J , K , L , M ve N ile başlayanlar örtük olarak tamsayı tipindeydi ve hepsi
diğerleri örtük olarak kayan noktaydı. Bu toplantı için harflerin seçimi
O zamanlar bilim adamları ve mühendislerin mektupları kullandıkları gerçeğine dayanıyordu.
değişken indisler olarak, genellikle i, j ve k. Cömertlik bir jest olarak, Fortran'ın
tasarımcılar üç ek harf daha attı.
Fortran geliştirme grubu tarafından yapılan en cüretkar iddia
dilin tasarımı, derleyici tarafından üretilen makine kodunun
elle üretilebilecek olanın yaklaşık yarısı kadar verimli olacaktır. 1 Bu, daha
her şeyden önce, potansiyel kullanıcılar hakkında şüpheci davrandı ve birçok şeyi engelledi.
Gerçek yayınlanmadan önce Fortran'a ilgi duyuyor. Neredeyse herkesi şaşırtacak şekilde,
ancak, Fortran geliştirme grubu verimlilik konusundaki hedefine neredeyse ulaştı.
18 işçi-yıllık emeğin en büyük kısmı, ilk yapıyı inşa etmek için kullanıldı.
piller optimizasyon için harcanmıştı ve sonuçlar oldukça etkiliydi.
Fortran'ın erken başarısı, İngiltere'de yapılan bir anketin sonuçlarıyla gösterilmektedir.
Nisan 1958. O zaman, 704'ler için yazılan kodun kabaca yarısı,
çoğu programlamanın şüpheciliğine rağmen Fortran'da yazılıyor
dünya sadece bir yıl önce.
2.3.4 Fortran II
Fortran II derleyicisi 1958 baharında dağıtıldı.
Fortran I derleme sistemindeki hataların ve bazı önemli
dilin özellikleri, en önemlisi bağımsız iletişim
alt programların pilasyonu. Bağımsız derleme olmadan, herhangi bir değişiklik
program, tüm programın yeniden derlenmesini gerektiriyordu. Fortran I eksikliği
zayıf güvenilirliği ile birleştiğinde bağımsız derleme yeteneği
704, programların uzunluğuna yaklaşık 300 ila 300 arasında pratik bir kısıtlama getirdi.
400 satır (Wexelblat, 1981, s. 68). Daha uzun programların şansı zayıftı.
bir makine arızası meydana gelmeden önce tamamen derleniyor. Kabiliyet
kısaltılmış alt programların önceden derlenmiş makine dili sürümlerini dahil etme
derleme sürecini önemli ölçüde geliştirdi ve çok geliştirmeyi pratik hale getirdi
daha büyük programlar
1. Aslında, Fortran ekibi, derleyicileri tarafından oluşturulan kodun hiçbir şey olamayacağına inanıyordu.
el yazısı makine kodunun yarısından daha az hızlı, yoksa dil tarafından benimsenmez
kullanıcılar.

Sayfa 66
2.3.5 Fortrans IV, 77, 90, 95, 2003 ve 2008
Bir Fortran III geliştirildi, ancak hiçbir zaman geniş çapta dağıtılmadı. Fortran IV,
ancak, kendi dünyasının en yaygın kullanılan programlama dillerinden biri haline geldi.
zaman. 1960 ile 1962 arasında gelişti ve For- olarak standardize edildi.
tran 66 (ANSI, 1966), ancak bu isim nadiren kullanılıyordu. Fortran IV bir
Fortran II üzerinde birçok yönden iyileştirme. En önemli eklentileri arasında
değişkenler için açık tip bildirimler, mantıksal bir If yapısı ve
alt programları diğer alt programlara parametre olarak geçirme yeteneği.
Fortran IV, yeni standart haline gelen Fortran 77 ile değiştirildi
1978'de (ANSI, 1978a). Fortran 77, Fortran IV'ün özelliklerinin çoğunu korudu
ve eklenen karakter dizisi işleme, mantıksal döngü kontrol ifadeleri ve bir
Eğer isteğe bağlı olan Else maddede.
Fortran 90 (ANSI, 1992), Fortran 77'den önemli ölçüde farklıydı.
en önemli eklemeler dinamik diziler, kayıtlar, işaretçiler, çoklu
seçim bildirimi ve modüller. Ayrıca Fortran 90 alt programları
yinelemeli olarak çağrılabilir.
Fortran 90 tanımına dahil edilen yeni bir kavram şuydu:
bazı dil özelliklerini önceki sürümlerden kaldırma. Fortran 90 dahil iken
Fortran 77'nin tüm özellikleri, dil tanımı bir kon-
dilin sonraki sürümünde kaldırılması önerilen yapılar.
Fortran 90, görünümü değiştiren iki basit sözdizimsel değişiklik içeriyordu.
hem programların hem de dili açıklayan literatürün İlk olarak, gerekli
belirli karakter konumlarının kullanılmasını gerektiren sabit kod biçimi.
ifadelerin cific kısımları çıkarıldı. Örneğin, ifade etiketleri görünebilir
sadece ilk beş pozisyonda ve ifadeler yedinciden önce başlayamadı
konum. Bu katı kod biçimlendirmesi, delikli kartların kullanımı etrafında tasarlanmıştır.
İkinci değişiklik, FORTRAN'ın resmi yazılışının Fortran olmasıydı.
Bu değişikliğe, tüm büyük harfleri kullanma kuralındaki değişiklik eşlik etti.
Fortran programlarında anahtar kelimeler ve tanımlayıcılar için harfler. Yeni kongre oldu
anahtar kelimelerin ve tanımlayıcıların yalnızca ilk harfinin büyük harf olacağı.
Fortran 95 (INCITS/ISO/IEC, 1997), lan-
guage, ancak yalnızca birkaç değişiklik yapıldı. Diğer şeylerin yanı sıra, yeni bir yineleme
Fortran programlarını paralelleştirme görevini kolaylaştırmak için Forall yapısı eklendi.
Fortran 2003 (Metcalf ve diğerleri, 2004), nesne yönelimli pro-
gramlama, parametreli türetilmiş türler, prosedür işaretçileri ve birlikte çalışma
C programlama dili ile yeteneği.
Fortran'ın en son sürümü, Fortran 2008 (ISO/IEC 1539-1, 2010) eklendi
paralel sağlayan yerel kapsamları, ortak dizileri tanımlamak için bloklar için destek
yürütme modeli ve DO CONCURRENT yapısı, olmadan döngüleri belirtmek için
karşılıklı bağımlılıklar.
2.3.6 Değerlendirme
Orijinal Fortran tasarım ekibi, dil tasarımını yalnızca bir zorunluluk olarak düşündü.
Çevirmen tasarlamanın kritik görevine giriş. Üstelik,
Fortran'ın bilgisayarlarda kullanılacağı asla akıllarına gelmedi.
2.3 IBM 704 ve Fortran 45

Sayfa 67
46
Bölüm 2 Başlıca Programlama Dillerinin Evrimi
IBM tarafından üretilmiştir. Gerçekten de Fortran'ı inşa etmeyi düşünmek zorunda kaldılar.
diğer IBM makineleri için derleyiciler, yalnızca 704'ün halefi olduğu için
709, 704 Fortran derleyicisi yayınlanmadan önce duyuruldu. Etki
Fortran'ın bilgisayar kullanımı konusunda sahip olduğu, tüm alt-
sıralı programlama dilleri Fortran'a borçludur, gerçekten etkileyici
tasarımcılarının mütevazı hedefleri ışığında.
Fortran I'in ve 90'dan önceki tüm ardıllarının özelliklerinden biri,
derleyicileri son derece optimize eden, tüm değişkenler için türlerin ve depolamanın olmasıydı.
çalışma zamanından önce düzeltildi. Yürütme sırasında hiçbir yeni değişken veya alan tahsis edilemedi.
zaman. Bu, esnekliğin basitliğe ve verimliliğe feda edilmesiydi. ortadan kaldırır-
özyinelemeli alt programların olasılığını ortaya çıkardı ve uygulanmasını zorlaştırdı
dinamik olarak büyüyen veya şekil değiştiren veri yapıları. tabiki çeşitleri
erken sürümlerin geliştirildiği sırada oluşturulan programlar
Fortran'ın doğası esas olarak sayısaldı ve karşılaştırıldığında basitti.
daha yeni yazılım projeleri ile. Bu nedenle, fedakarlık büyük değildi.
Fortran'ın genel başarısını abartmak zordur: Dramatik bir şekilde
bilgisayarların kullanım şeklini değiştirdi. Bu, elbette, büyük ölçüde,
yaygın olarak kullanılan ilk üst düzey dildir. Kavramlarla karşılaştırıldığında
ve daha sonra geliştirilen diller, Fortran'ın ilk sürümleri çeşitli zorluklardan muzdariptir.
beklendiği gibi yollar. Sonuçta, karşılaştırma yapmak adil olmaz.
performans ve konfor ile 1910 Model T Ford'un performansı ve konforu
2013 Ford Mustang'in konforu. Bununla birlikte, yetersizliklerine rağmen,
Fortran yazılımına yapılan büyük yatırımın ivmesi olan Fortran,
diğer faktörler, onu yarım yüzyıldan fazla bir süredir kullanımda tutuyor.
ALGOL 60'ın tasarımcılarından Alan Perlis, 1978'de Fortran için şunları söyledi:
“Fortran, bilgisayar dünyasının ortak dilidir . Bu, dilin
kelimenin fuhuş anlamında değil, kelimenin en iyi anlamıyla sokaklar.
Ve hayatta kaldı ve hayatta kalacak çünkü dikkat çekici bir şekilde ortaya çıktı.
çok hayati bir ticaretin faydalı bir parçası” (Wexelblat, 1981, s. 161).
Aşağıdaki, bir Fortran 95 programının bir örneğidir:
! Fortran 95 Örnek program
! Girdi: List_Len'in daha az olduğu bir tamsayı, List_Len
!
100'den fazla, ardından List_Len-Integer değerleri
! Çıktı: Daha büyük olan girdi değerlerinin sayısı
!
tüm girdi değerlerinin ortalamasından
örtük hiçbiri
Tamsayı Boyut(99) :: Int_List
Tamsayı :: List_Len, Sayaç, Toplam, Ortalama, Sonuç
Sonuç= 0
Toplam = 0
Oku *, List_Len
Eğer ((List_Len > 0) .AND. (List_Len < 100)) O zaman
! Girdi verilerini bir diziye okuyun ve toplamını hesaplayın
Sayacını Yap = 1, List_Len
Oku *, Int_List(Sayaç)
Toplam = Toplam + Int_List(Sayaç)

Sayfa 68
Bitir
! Ortalamayı hesapla
Ortalama = Toplam / List_Len
! Ortalamadan büyük olan değerleri sayın
Sayacını Yap = 1, List_Len
If (Int_List(Counter) > Ortalama) Sonra
Sonuç = Sonuç + 1
Bitir
Bitir
! sonucu yazdır
Yazdır *, 'Değer sayısı > Ortalama:', Sonuç
Başka
Yazdır *, 'Hata - liste uzunluğu değeri yasal değil'
Bitir
Program Sonu Örneği
2.4 Fonksiyonel Programlama: LISP
İlk işlevsel programlama dili, dil sağlamak için icat edildi.
İlk uygulamalardan kaynaklanan ihtiyaç duyulan liste işleme özellikleri
yapay zeka (AI) alanında.
2.4.1 Yapay Zekanın Başlangıcı ve Liste İşleme
Yapay zekaya ilgi 1950'lerin ortalarında birçok yerde ortaya çıktı. Bunun birazı
ilgi dilbilimden, bazıları psikolojiden, bazıları matematikten doğdu.
ematik. Dilbilimciler doğal dil işleme ile ilgileniyorlardı. psikolo-
özü, insan bilgi depolama ve geri alımını modellemekle ilgileniyordu.
beynin diğer temel süreçleri gibi. Matematikçiler inter-
teorem kanıtlama gibi belirli akıllı süreçlerin mekanikleştirilmesinde önemliydi.
Bütün bu araştırmalar aynı sonuca vardı: Bazı yöntemler
bilgisayarların bağlantılı listelerdeki sembolik verileri işlemesine izin verecek şekilde geliştirilmelidir. de
zaman, çoğu hesaplama dizilerdeki sayısal veriler üzerindeydi.
Liste işleme kavramı Allen Newell, JC Shaw tarafından geliştirilmiştir.
ve RAND Corporation'dan Herbert Simon. İlk olarak bir sınıfta yayınlandı.
İlk AI programlarından biri olan Logic Theorist, 2 ve
uygulanabileceği bir dil (Newell ve Simon, 1956). bu
IPL-I (Bilgi İşleme Dili I) olarak adlandırılan dil hiçbir zaman
bahsetti. Bir sonraki sürüm olan IPL-II, bir RAND Johnniac üzerinde uygulandı.
bilgisayar. IPL'nin gelişimi 1960 yılına kadar devam etti.
IPL-V yayımlandı (Newell ve Tonge, 1960). IPL'nin düşük seviyesi
dillerin yaygın olarak kullanılmasına engel olmuştur. Onlar aslında montaj lan-
içinde bir tercüman ile uygulanan varsayımsal bir bilgisayar için
2. Mantık Teorisyeni, önermeler hesabındaki teoremlerin kanıtlarını keşfetti.
2.4 Fonksiyonel Programlama: LISP 47

Sayfa 69
48
Bölüm 2 Başlıca Programlama Dillerinin Evrimi
liste işleme talimatları dahil edildi. IPL'yi koruyan bir diğer faktör
dillerin popüler hale gelmesinin nedeni, belirsiz bir şekilde uygulanmalarıydı.
Johnniac makinesi.
IPL dillerinin katkıları liste tasarımında ve
liste işlemenin uygulanabilir ve yararlı olduğunu gösterdi.
IBM, 1950'lerin ortalarında yapay zeka ile ilgilenmeye başladı ve teorem kanıtını seçti.
gösteri alanı olarak kullanılmaktadır. O zaman, Fortran projesi henüz tamamlanmamıştı.
yol. Fortran I derleyicisinin yüksek maliyeti, IBM'i listelerinin
işleme, yeni bir formdan ziyade Fortran'a eklenmelidir.
dilim. Böylece Fortran Liste İşleme Dili (FLPL) tasarlandı.
ve Fortran'ın bir uzantısı olarak uygulandı. oluşturmak için FLPL kullanıldı.
O zamanlar en kolay alan olarak kabul edilen düzlem geometrisi için teorem ispatı
mekanik teorem ispatı için.
2.4.2 LISP Tasarım Süreci
MIT'den John McCarthy, IBM Information'da bir yaz pozisyonu aldı
1958'de Araştırma Departmanı. Yaz için amacı araştırma yapmaktı.
sembolik hesaplamalar ve bunu yapmak için bir dizi gereksinim geliştirmek
hesaplamalar. Pilot örnek bir problem alanı olarak, farklılaştırmayı seçti.
cebirsel ifadeler. Bu çalışmadan dil gereksinimlerinin bir listesi geldi.
Bunlar arasında matematiksel fonksiyonların kontrol akış yöntemleri vardı: yineleme.
sion ve koşullu ifadeler. Mevcut tek yüksek seviyeli dil
zaman, Fortran I, bunların hiçbirine sahip değildi.
Sembolik-farklılaştırma yatırımlarından doğan bir başka gereklilik.
tigation, dinamik olarak tahsis edilmiş bağlantılı listelere ve bir tür
terkedilmiş listelerin örtük olarak serbest bırakılması. McCarthy basitçe onun
açık ayırma ile karmaşık hale getirilecek farklılaşma için zarif algoritma
ifadeler.
FLPL özyinelemeyi, koşullu ifadeleri, dinamik
depolama tahsisi veya örtülü serbest bırakma, McCarthy için yeni bir
dile ihtiyaç vardı.
McCarthy 1958 sonbaharında MIT'ye döndüğünde, o ve Marvin
Minsky, Araştırma Laboratuvarı'ndan sağlanan fonla MIT AI Projesini kurdu.
Elektronik için tory. Projenin ilk önemli çabası,
liste işleme için bir yazılım sistemi. Başlangıçta uygulamak için kullanılacaktı
McCarthy tarafından önerilen ve Advice Taker adlı bir program. 3 Bu uygulama
liste işleme dili LISP'nin geliştirilmesi için itici güç oldu.
LISP'nin ilk versiyonuna bazen "saf LISP" denir çünkü o tamamen bir
Fonksiyonel dil. Aşağıdaki bölümde, gelişimini açıklıyoruz.
saf LISP.
3. Advice Taker, bilgileri resmi bir dilde yazılmış ve kullanılan cümlelerle temsil etmiştir.
ne yapılacağına karar vermek için mantıklı bir çıkarım süreci.

Sayfa 70
2.4.3 Dile Genel Bakış
2.4.3.1 Veri Yapıları
Pure LISP sadece iki tür veri yapısına sahiptir: atomlar ve listeler. atomlar
tanımlayıcı biçimine sahip semboller veya sayısal değişmezler. con-
Sembolik bilgilerin bağlantılı listelerde saklanması doğaldır ve
IPL-II. Bu tür yapılar, herhangi bir noktada ekleme ve silme işlemlerine izin verir.
daha sonra liste işlemenin gerekli bir parçası olduğu düşünüldü. Olay-
Ancak, LISP programlarının bu işlemleri nadiren gerektirdiğine karar verildi.
Listeler, elemanları parantez ile sınırlandırılarak belirtilir. Basit
elementlerin atomlarla sınırlı olduğu listeler şu şekildedir:
(ABCD)
İç içe liste yapıları da parantez içinde belirtilir. Örneğin, liste
(A (BC) D (E (FG)))
dört unsurdan oluşur. Birincisi A atomudur ; ikincisi alt listedir
(M.Ö.) ; üçüncüsü D atomudur ; dördüncüsü alt listedir (E (FG)) ,
ikinci öğesi olarak alt liste (FG) .
Dahili olarak, listeler tek bağlantılı liste yapıları olarak saklanır;
düğüm iki işaretçiye sahiptir ve bir liste öğesini temsil eder. içeren bir düğüm
atomun ilk işaretçisi, atomun bazı temsillerine işaret eder, örneğin
sembolü veya sayısal değeri veya bir alt listeye işaretçi olarak. Alt liste için bir düğüm
öğenin ilk işaretçisi alt listenin ilk düğümünü gösterir. Hem de
durumlarda, bir düğümün ikinci işaretçisi listenin bir sonraki öğesini gösterir. Bir liste
ilk öğesine bir işaretçi tarafından başvurulur.
Daha önce gösterilen iki listenin dahili temsilleri,
Şekil 2.2. Bir listenin öğelerinin yatay olarak gösterildiğine dikkat edin. Son
bir liste öğesinin halefi yoktur, bu nedenle bağlantısı NIL'dir ve şu şekilde temsil edilir:
Şekil 2.2 elemanda çapraz bir çizgi olarak. Alt listeler aynı şekilde gösterilir
yapı.
2.4.3.2 Fonksiyonel Programlamada Süreçler
LISP, işlevsel bir programlama dili olarak tasarlanmıştır. Tüm hesaplama bir
tamamen işlevsel program, işlevlerin argümanlara uygulanmasıyla gerçekleştirilir.
Ne atama ifadeleri ne de zorunlu olarak bol olan değişkenler
dil programları, işlevsel dil programlarında gereklidir. Üstelik,
yinelemeli işlemler özyinelemeli işlev çağrılarıyla belirtilebilir,
(döngüler) gereksizdir. Fonksiyonel programlamanın bu temel kavramları,
zorunlu bir dilde programlamadan önemli ölçüde farklıdır.
2.4 Fonksiyonel Programlama: LISP 49

Sayfa 71
50
Bölüm 2 Başlıca Programlama Dillerinin Evrimi
2.4.3.3 LISP Sözdizimi
LISP, zorunlu dillerden çok farklıdır, çünkü ikisi de bir işlevdir.
programlama dilidir ve LISP programlarının görünümü
Java veya C++ gibi dillerdekilerden çok farklı. Örneğin, sözdizimi
of Java, İngilizce ve cebirin karmaşık bir karışımıdır, LISP'in sözdizimi ise
sadeliğin bir modelidir. Program kodu ve veriler tamamen aynı forma sahiptir:
parantez içindeki listeler. Listeyi tekrar düşünün
(ABCD)
Veri olarak yorumlandığında, dört öğeden oluşan bir listedir. Kod olarak görüntülendiğinde,
A adlı fonksiyonun B , C ve D üç parametresine uygulanmasıdır .
2.4.4 Değerlendirme
LISP, çeyrek yüzyıl boyunca yapay zeka uygulamalarına tamamen hakim oldu. Çok
LISP'in son derece verimsiz olma ününün nedeni ortadan kaldırılmıştır.
Birçok çağdaş uygulama derlenir ve ortaya çıkan kod
kaynak kodunu bir yorumlayıcıda çalıştırmaktan çok daha hızlıdır. ek olarak
AI'daki başarı, LISP, kanıtlanmış fonksiyonel programlamaya öncülük etti.
programlama dillerinde canlı bir araştırma alanı olmak. Bölüm 1'de belirtildiği gibi,
Birçok programlama dili araştırmacısı, işlevsel programlamanın bir
yazılım geliştirmeye prosedürel programlamadan çok daha iyi bir yaklaşım
zorunlu dilleri kullanma.
B
C
D
F
G
B
C
E
A
D
A
Şekil 2.2
İç temsil
iki LISP listesinden

Sayfa 72
Aşağıda bir LISP programı örneği verilmiştir:
; LISP Örnek işlevi
; Aşağıdaki kod, bir LISP yüklem işlevini tanımlar
; argüman olarak iki liste alan ve True değerini döndüren
; iki liste eşitse, aksi halde NIL (yanlış)
(DEFUN equal_lists (lis1 lis2)
(KOND
((ATOM lis1) (EQ lis1 lis2))
((ATOM lis2) NIL)
((equal_lists (CAR lis1) (CAR lis2))
(equal_lists (CDR lis1) (CDR lis2)))
(T NIL)
)
)
2.4.5 LISP'nin İki Torunu
LISP'nin iki lehçesi artık yaygın olarak kullanılmaktadır: Scheme ve Common LISP. Bunlar
aşağıdaki alt bölümlerde kısaca tartışılmaktadır.
2.4.5.1 Şema
Scheme dili, 1970'lerin ortalarında MIT'den ortaya çıktı (Dybvig, 2003).
Küçük boyutu, özel statik kapsam belirleme kullanımı (tartışılan) ile karakterize edilir.
Bölüm 5) ve işlevlerin birinci sınıf varlıklar olarak ele alınması. birinci sınıf olarak
varlıklar, Şema fonksiyonları değişkenlere atanabilir, parametre olarak geçirilebilir,
ve işlev uygulamalarının değerleri olarak döndürülür. Onlar da ele-
listeler. LISP'nin ilk sürümleri bu yeteneklerin hepsini sağlamadı.
ne de statik kapsam kullanmadılar.
Basit sözdizimi ve semantik ile küçük bir dil olarak, Scheme çok uygundur
fonksiyonel programlama dersleri gibi eğitim uygulamalarına ve
programlamaya genel girişler. Şema bazı ayrıntılı olarak açıklanmıştır
15. Bölüm
2.4.5.2 Ortak LISP
1970'lerde ve 1980'lerin başında, çok sayıda farklı LISP lehçesi
geliştirilmiş ve kullanılmıştır. Bu, bilinen taşınabilirlik eksikliği sorununa yol açtı.
çeşitli lehçelerde yazılmış programlar arasında yer alır. Ortak LISP (Graham,
1996) bu durumu düzeltmek amacıyla oluşturuldu. Ortak LISP (önceki değeri)
LISP'in çeşitli lehçelerinin özelliklerini birleştirerek tasarlanmıştır.
1980'lerin başında, Scheme dahil olmak üzere, tek bir dilde. Böyle bir karışım olmak,
Common LISP, nispeten büyük ve karmaşık bir dildir. Ancak onun temeli,
saf LISP'dir, dolayısıyla sözdizimi, ilkel işlevleri ve temel doğası
o dilden.
2.4 Fonksiyonel Programlama: LISP 51

Sayfa 73
52
Bölüm 2 Başlıca Programlama Dillerinin Evrimi
Dinamik kapsam belirlemenin sağladığı esnekliğin yanı sıra
statik kapsam belirlemenin basitliği, Common LISP her ikisine de izin verir. Varsayılan kapsam
değişkenler için statiktir, ancak bir değişkeni özel olarak bildirerek , bu değişken
dinamik olarak kapsamlı hale gelir.
Ortak LISP, aşağıdakiler dahil olmak üzere çok sayıda veri türüne ve yapısına sahiptir:
kayıtlar, diziler, karmaşık sayılar ve karakter dizileri. Ayrıca bir formu var
erişim sağlayan işlev ve veri koleksiyonlarını modülerleştirmek için paketler
kontrol.
Ortak LISP, Bölüm 15'te daha ayrıntılı olarak açıklanmaktadır.
2.4.6 İlgili Diller
ML ( M eta L anguage; Ullman, 1998) ilk olarak 1980'lerde tasarlanmıştır
Robin Milner, Edinburgh Üniversitesi'nde bir program için üst dil olarak
Hesaplanabilir İşlevler için Mantık adlı doğrulama sistemi (LCF; Milner et
al., 1990). ML öncelikle işlevsel bir dildir, ancak aynı zamanda impera-
tif programlama. LISP ve Scheme'den farklı olarak, her değişkenin türü ve
ML'deki ifade, derleme zamanında belirlenebilir. Türler ile ilişkilidir
isimlerden ziyade nesneler. İsimlerin ve ifadelerin türleri aşağıdakilerden çıkarılır:
onların bağlamı.
LISP ve Scheme'den farklı olarak ML, parantez içindeki işlevi kullanmaz.
lambda ifadelerinden kaynaklanan sözdizimi. Bunun yerine, ML'nin sözdizimi
Java ve C++ gibi zorunlu dillerinkine benzer.
Miranda, Kent Üniversitesi'nde David Turner (1986) tarafından geliştirildi.
1980'lerin başında Canterbury, İngiltere'de. Miranda kısmen
ML, SASL ve KRC dilleri. Haskell (Hudak ve Fasel, 1992)
Miranda'nın büyük bir kısmı. Miranda gibi, tamamen işlevsel bir dildir.
değişken yok ve atama ifadesi yok. Bir başka ayırt edici karakter-
Haskell'in özelliği tembel değerlendirme kullanmasıdır. Bu, hiçbir ifadenin olmadığı anlamına gelir.
değeri isteninceye kadar değerlendirilir. Bu, bazı şaşırtıcı yeteneklere yol açar
dilde.
Caml (Cousineau ve diğerleri, 1998) ve nesne yönelimli destekleyen lehçesi
programlama, OCaml (Smith, 2006), ML ve Haskell'den türemiştir. Nihayet,
F#, doğrudan OCaml'ye dayalı nispeten yeni yazılmış bir dildir. F# (Syme ve diğerleri,
2010), tüm .NET kitaplığına doğrudan erişimi olan bir .NET dilidir. Olmak
.NET dili ayrıca diğer .NET ile sorunsuz bir şekilde birlikte çalışabileceği anlamına gelir.
dilim. F# hem işlevsel programlamayı hem de prosedürel programı destekler.
ming. Ayrıca nesne yönelimli programlamayı tamamen destekler.
ML, Haskell ve F#, Bölüm 15'te daha ayrıntılı olarak tartışılmaktadır.
2.5 Gelişmişliğe Doğru İlk Adım: ALGOL 60
ALGOL 60'ın sonraki programlama dilleri üzerinde çok etkisi oldu
ve bu nedenle, dillerin herhangi bir tarihsel çalışmasında merkezi bir öneme sahiptir.

Sayfa 74
2.5.1 Tarihsel Arkaplan
ALGOL 60, evrensel bir programlama dili tasarlama çabalarının sonucuydu.
bilimsel uygulamalar için. 1954'ün sonlarında, Laning ve Zierler cebir sistemi
bir yıldan fazla bir süredir faaliyetteydi ve Fortran hakkındaki ilk rapor
yayınlanan. Fortran 1957'de gerçek oldu ve diğer birkaç üst düzey dil
geliştiriliyordu. Aralarında en dikkat çekeni, tasarlanmış olan BT idi.
Carnegie Tech'den Alan Perlis ve UNIVAC bilgisayarları için iki dil,
MATH-MATIC ve UNICODE. Program yapılan dillerin çoğalması
kullanıcılar arasında paylaşım zor. Ayrıca, yeni dillerin hepsi büyüyordu.
Bazıları UNIVAC bilgisayarları için ve bazıları
IBM 700 serisi makineler. Bu makineye bağımlı gelişmeye yanıt olarak
diller, Amerika Birleşik Devletleri'ndeki birkaç büyük bilgisayar kullanıcı grubu dahil
PAYLAŞ (IBM bilimsel kullanıcı grubu) ve KULLANIM (UNIVAC Scientific Exchange,
büyük ölçekli UNIVAC bilimsel kullanıcı grubu), Dernek'e bir dilekçe sundu.
Bir taahhüt oluşturmak üzere 10 Mayıs 1957'de Computing Machinery (ACM) için atıf
makineden bağımsız bir bilimsel oluşturmak için çalışma ve eylem önermek için tee
Programlama dili. Fortran aday olsa da,
evrensel bir dil haline gelmez, çünkü o zamanlar yalnızca IBM'e aittir.
Daha önce, 1955'te, GAMM (Uygulamalı Uygulamalar Derneği'nin Almanca kısaltması)
Matematik ve Mekanik) tek bir evrensel tasarlamak için bir komite oluşturmuştu.
makineden bağımsız algoritmik dil. Bu yeni dil arzusu
kısmen Avrupalıların IBM'in egemenliğine girme korkusundan kaynaklanıyordu. Geç saatlerde
1957, ancak, Birleşik Devletler'de birkaç üst düzey dilin ortaya çıkması
Devletler GAMM alt komitesini çabalarının genişletilmesi gerektiğine ikna etti
Amerikalıları da dahil etmek için ACM'ye bir davet mektubu gönderildi. Nisan içinde
1958, GAMM'den Fritz Bauer resmi teklifi ACM'ye sunduktan sonra,
iki grup resmi olarak ortak bir dil tasarım projesini kabul etti.
2.5.2 Erken Tasarım Süreci
GAMM ve ACM, ilk tasarım toplantısına dört üye gönderdi. bu
27 Mayıs - 1 Haziran 1958 tarihleri ​​arasında Zürih'te yapılan toplantı,
yeni dil için aşağıdaki hedefler:
• Dilin sözdizimi, standart matematiğe mümkün olduğunca yakın olmalıdır.
Ematical gösterim ve içinde yazılan programlar çok az okunabilir olmalıdır.
daha fazla açıklama.
• Algoritmaların tanımı için dili kullanmak mümkün olmalıdır
basılı yayınlarda.
• Yeni dildeki programlar mekanik olarak şu dile çevrilebilir olmalıdır:
makine dili.
İlk hedef, yeni dilin bilimsel amaçlar için kullanılacağını gösterdi.
O zamanlar birincil bilgisayar uygulama alanı olan programlama.
İkincisi, bilgisayar işi için tamamen yeni bir şeydi. Son
amaç, herhangi bir programlama dili için bariz bir zorunluluktur.
2.5 Gelişmişliğe Doğru İlk Adım: ALGOL 60 53

Sayfa 75
54
Bölüm 2 Başlıca Programlama Dillerinin Evrimi
Zürih toplantısı, belirtilen gereksinimleri karşılayan bir dil üretmeyi başardı.
ama tasarım süreci sayısız uzlaşma gerektirdi.
bireyler ve Atlantik'in iki yakası arasında. Bazı durumlarda, kom-
vaatler, büyük meselelerden çok,
etkilemek. Virgül (Avrupa yöntemi) mi yoksa virgül mü kullanılacağı sorusu
bir ondalık nokta için bir nokta (Amerikan yöntemi) bir örnektir.
2.5.3 ALGOL 58 Genel Bakış
Zürih toplantısında tasarlanan dile Uluslararası Dil adı verildi.
Algoritmik Dil (IAL). Tasarım sırasında lan-
ALGOrithmic Language için ALGOL olarak adlandırılabilir, ancak ad
komitenin uluslararası kapsamını yansıtmadığı için reddedilmiştir.
Ancak sonraki yıl adı ALGOL olarak değiştirildi ve
dil daha sonra ALGOL 58 olarak tanındı.
ALGOL 58 birçok yönden Fortran'ın soyundan geliyordu.
doğal. Fortran'ın birçok özelliğini genelleştirdi ve birkaç yeni özellik ekledi.
yapılar ve kavramlar. Bazı genellemelerin amacı ile ilgiliydi.
dili belirli bir makineye bağlamamak ve diğerleri
dili daha esnek ve güçlü hale getirir. Sadeliğin nadir bir kombinasyonu
ve zarafet çabadan ortaya çıktı.
ALGOL 58, veri türü kavramını resmileştirdi, ancak yalnızca değişkenler
kayan nokta gerektirmeyen açık beyan. fikrini ekledi
sonraki dillerin çoğunun dahil ettiği bileşik ifadeler. Bazı
Fortran'ın genelleştirilmiş özellikleri şunlardı:
Fortran I'in altı veya daha azıyla kısıtlamasının aksine, herhangi bir uzunluğa sahip olmasına izin verilir
karakterler; Fortran I'in aksine herhangi bir sayıda dizi boyutuna izin verildi
üçten fazla olmamak üzere sınırlama; dizilerin alt sınırı belirtilebilir
programcı tarafından, Fortran'da ise örtük olarak 1 idi; iç içe seçim
Fortran I'de durum böyle değildi, ifadelere izin verildi.
ALGOL 58, atama operatörünü oldukça alışılmadık bir şekilde aldı.
Zuse formu kullandı
ifade => değişken
Plankalkül'deki atama ifadesi için. Plankalkül henüz
ALGOL 58 komitesinin bazı Avrupalı ​​üyeleri yayınlandı.
diline aşinaydı. Heyet Plankalkül ile uğraştı
atama formu ancak, çünkü karakter kümesi sınırlamaları hakkında argümanlardan 4
büyüktür sembolü iki nokta üst üste olarak değiştirildi. Daha sonra, büyük ölçüde ısrarı üzerine
Amerikalılar, tüm ifade Fortran formuna çevrildi
değişken := ifade
Avrupalılar bunun tam tersini tercih ettiler, ancak bu tam tersi olurdu.
Fortran.
4. O zamanın kart zımbaları, büyüktür sembolünü içermiyordu.

Sayfa 76
2.5.4 ALGOL 58 Raporunun Alınması
Aralık 1958'de ALGOL 58 raporunun yayınlanması (Perlis ve Samelson,
1958) büyük bir coşkuyla karşılandı. Amerika Birleşik Devletleri'nde, yeni
dil daha çok programlama dili için bir fikir koleksiyonu olarak görülüyordu.
evrensel bir standart dil olarak tasarım. Aslında, ALGOL 58 raporu
bitmiş bir ürün değil, bunun için bir ön belge olması gerekiyordu.
uluslararası tartışma. Bununla birlikte, üç ana tasarım ve uygulama
çabalar raporu temel olarak kullandı. Michigan Üniversitesi'nde, MAD
dil doğdu (Arden ve diğerleri, 1961). ABD Deniz Elektroniği Grubu pro-
NELIAC dilini oluşturdu (Huskey ve diğerleri, 1963). Sistem Geliştirmede
Corporation, JOVIAL tasarlanmış ve uygulanmıştır (Shaw, 1963). NEŞELİ,
Jules'un Uluslararası Cebirsel Dilinin Kendi Versiyonunun kısaltması,
yaygın kullanıma ulaşmak için ALGOL 58'e dayalı tek dili temsil eder
(Jules, JOVIAL'in tasarımcılarından biri olan Jules I. Schwartz'dı). JOVIAL oldu
ABD Hava Kuvvetleri'nin resmi bilimsel dili olduğu için yaygın olarak kullanılmaktadır.
çeyrek asırdır.
ABD bilgi işlem topluluğunun geri kalanı yeni lan-
ölçü. İlk başta, hem IBM hem de başlıca bilimsel kullanıcı grubu SHARE,
ALGOL 58'i benimsemek. IBM, rapordan kısa bir süre sonra bir uygulamaya başladı
yayınlandı ve SHARE, aşağıdakileri incelemek için SHARE IAL adlı bir alt komite kurdu.
dilim. Alt komite daha sonra ACM standart-
ALGOL 58'i ve IBM'in bunu 700 serisi bilgisayarların tümü için uyguladığını.
Ancak coşku kısa sürdü. 1959 baharında, hem IBM
ve SHARE, Fortran deneyimleriyle, acıdan bıkmıştı.
ve yeni bir dile başlamanın maliyeti, hem gelişme hem de
birinci nesil derleyicileri kullanmak ve kullanıcıları yeni
ve onları kullanmaya ikna etmek. 1959 yılının ortalarında hem IBM hem de
SHARE, Fortran'da öyle bir kazanılmış çıkar geliştirmişti ki,
olarak saklayın ve böylece IBM 700 serisi makineleri için bilimsel dili
ALGOL 58'i terk etmek.
2.5.5 ALGOL 60 Tasarım Süreci
1959'da ALGOL 58, hem Avrupa'da hem de Birleşik Devletler'de hararetli bir şekilde tartışıldı.
Devletler. Çok sayıda önerilen değişiklik ve ekleme yayınlandı
Avrupa ALGOL Bülteninde ve ACM İletişimlerinde. Biri
1959'un en önemli olayı Zürih'in çalışmalarının sunumuydu.
Uluslararası Bilgi İşleme Konferansı komitesi,
orada Backus, programın sözdizimini tanımlamak için yeni notasyonunu tanıttı.
daha sonra BNF (Backus-Naur formu) olarak bilinen ming dilleri. BNF
Bölüm 3'te ayrıntılı olarak açıklanmaktadır.
1960 yılının Ocak ayında, bu kez Paris'te ikinci ALGOL toplantısı yapıldı.
Toplantının amacı, daha önce önerilen 80 öneriyi tartışmaktı.
resmi olarak değerlendirilmek üzere sunulmuştur. Danimarkalı Peter Naur
ALGOL'un gelişiminde yoğun bir şekilde yer almış olmasına rağmen,
2.5 Gelişmişliğe Doğru İlk Adım: ALGOL 60 55

Sayfa 77
56
Bölüm 2 Başlıca Programlama Dillerinin Evrimi
Zürih grubunun bir üyesi. Kitabı yaratan ve yayınlayan Naur'du.
ALGOL Bülteni. Backus'un makalesini incelemek için çok zaman harcadı.
BNF'yi tanıttı ve BNF'nin resmi olarak tanımlamak için kullanılması gerektiğine karar verdi
1960 toplantısının sonuçları. Birkaç nispeten küçük değişiklik yaptıktan sonra
BNF, önerilen yeni dilin tanımını BNF'ye yazdı ve
toplantının başında 1960 grubunun üyelerine dağıttı.
2.5.6 ALGOL 60 Genel Bakış
1960 toplantısı sadece altı gün sürmesine rağmen, yapılan değişiklikler
ALGOL 58 dramatikti. En önemli yeni gelişmeler arasında
şunlardı:
• Blok yapı konsepti tanıtıldı. Bu programa izin verdi-
yeni veri ortamlarını tanıtarak programların bölümlerini yerelleştirmek,
veya kapsamları.
• Parametrelerin alt programlara iletilmesi için iki farklı yola izin verildi:
değere göre geç ve isme göre geç.
• Prosedürlerin özyinelemeli olmasına izin verildi. ALGOL 58 açıklaması
bu konuda belirsiz. Bu özyinelemenin yeni olmasına rağmen,
zorunlu diller, LISP zaten özyinelemeli işlevler sağlamıştı
1959.
• Yığın dinamik dizilere izin verildi. Yığın dinamik dizisi, bunun için
alt simge aralığı veya aralıkları değişkenler tarafından belirtilir, böylece
dizi, depolamanın diziye tahsis edildiği zamanda ayarlanır;
yürütme sırasında beyana ulaşıldığında. Yığın dinamik diziler
Bölüm 6'da ayrıntılı olarak açıklanmaktadır.
Başarı üzerinde dramatik bir etkisi olabilecek çeşitli özellikler veya
dilin başarısızlığı önerildi ve reddedildi. arasında en önemli
bunlar, formatlanmış giriş ve çıkış ifadeleriydi ve atlandı
çünkü makineye bağımlı oldukları düşünülüyordu.
ALGOL 60 raporu Mayıs 1960'ta yayınlandı (Naur, 1960). bir numara
Dil betimlemesinde hâlâ belirsizlikler vardı ve üçüncü bir görüşme
Sorunları çözmek için Nisan 1962'de Roma'da yapılması planlandı. Bu işte
grupla tanışmak sadece problemlerle ilgilendi; dile hiçbir ekleme yapılmadı
izin verilmiş. Bu toplantının sonuçları “Revize Edilmiş” başlığı altında yayınlandı.
Algoritmik Dil Üzerine Rapor ALGOL 60” (Backus ve diğerleri, 1963).
2.5.7 Değerlendirme
ALGOL 60 bazı açılardan büyük bir başarıydı; başka şekillerde, kasvetliydi
arıza. Hemen hemen kabul edilebilir tek yöntem olmayı başardı.
bilgi işlem literatüründe algoritmaları iletmenin resmi araçları ve
20 yıldan fazla bir süre öyle kaldı. Her zorunlu programlama dili
1960'dan beri tasarlanan ALGOL 60'a bir şeyler borçludur. Aslında, çoğu doğrudan

Sayfa 78
veya dolaylı torunlar; örnekler arasında PL/I, SIMULA 67, ALGOL 68, C,
Pascal, Ada, C++, Java ve C#.
ALGOL 58/ALGOL 60 tasarım çabası, uzun bir ilkler listesi içeriyordu. o
uluslararası bir grubun bir program tasarlama girişiminde bulunduğu ilk zamandı.
ming dili. Makine bağımsız olarak tasarlanan ilk dildi.
asılı. Aynı zamanda sözdizimi resmi olarak tanımlanan ilk dildi.
BNF formalizminin bu başarılı kullanımı, birkaç önemli alan başlattı.
bilgisayar bilimi: resmi diller, ayrıştırma teorisi ve BNF tabanlı derleyici
tasarım. Son olarak, ALGOL 60'ın yapısı makine mimarisini etkiledi. İçinde
Bunun en çarpıcı örneği, dilin bir uzantısı olarak kullanılmıştır.
Bir dizi büyük ölçekli bilgisayarın sistem dili olan Burroughs B5000,
için bir donanım yığını ile tasarlanmış B6000 ve B7000 makineleri,
blok yapısını ve özyinelemeli alt programlarını verimli bir şekilde uygulamak
dilim.
Madalyonun diğer tarafında ALGOL 60 hiçbir zaman yaygın bir kullanıma kavuşamadı.
Birleşik Devletlerde. Avrupa'da bile, Avrupa'dan daha popülerdi.
Amerika Birleşik Devletleri, hiçbir zaman baskın dil olmadı. bir numara var
kabul görmemesinin nedenlerindendir. Bir kere, bazı özellikleri
ALGOL 60 çok esnek çıktı; anlamayı zorlaştırdılar
ve uygulama verimsizdir. Buna en iyi örnek, isme göre geçiştir.
Bölümde açıklanan alt programlara parametre aktarma yöntemi
9. ALGOL 60'ı uygulamanın zorlukları, Rutishauser'ın
1967'de, eğer varsa, birkaç uygulamanın tam ALGOL'u içerdiğine dair açıklama
60 dil (Rutishauser, 1967, s. 8).
Dilde girdi ve çıktı ifadelerinin olmaması da bir diğer önemli noktaydı.
kabul görmemesinin nedenidir. Uygulamaya bağlı giriş/çıkış
programların diğer bilgisayarlara taşınmasını zorlaştırdı.
İronik olarak, bilgisayar bilimine en önemli katkılardan biri
ALGOL 60, BNF ile ilişkili olması da kabul görmemesinde bir faktördü.
BNF şimdi basit ve zarif bir sözdizimi tanımlama aracı olarak kabul edilse de,
1960'da garip ve karmaşık görünüyordu.
Son olarak, başka birçok sorun olmasına rağmen,
Kullanıcılar arasında Fortran ve IBM'in desteğinin olmaması muhtemelen en çok
ALGOL 60'ın yaygın olarak kullanılmamasında önemli faktörler.
ALGOL 60 çabası hiçbir zaman tam anlamıyla tamamlanmamıştı.
yanlışlar ve belirsizlikler her zaman dil tanımının bir parçasıydı (Knuth,
1967).
Aşağıda bir ALGOL 60 programının bir örneği verilmiştir:
yorum ALGOL 60 Örnek Program
Girdi: listlen'in şundan küçük olduğu bir tamsayı, listlen
100, ardından listlen-integer değerleri
Çıktı: Daha büyük olan girdi değerlerinin sayısı
tüm girdi değerlerinin ortalaması;
başlamak
tamsayı dizi intlist [1:99];
2.5 Gelişmişliğe Doğru İlk Adım: ALGOL 60 57

Sayfa 79
58
Bölüm 2 Başlıca Programlama Dillerinin Evrimi
tamsayı listlen, sayaç, toplam, ortalama, sonuç;
toplam := 0;
sonuç := 0;
readint (listlen);
if (listlen > 0) ∧ (listlen < 100) o zaman
başlamak
yorum Bir diziye girdiyi okuyun ve ortalamayı hesaplayın;
için sayaç: 1 = aşama 1 kadar listlen yapmak
başlamak
readint (intlist[sayaç]);
toplam := toplam + iç liste[sayaç]
son;
yorum Ortalamayı hesaplayın;
ortalama := toplam / listelen;
yorum > ortalama olan giriş değerlerini sayın;
için sayaç: 1 = aşama 1 kadar listlen yapmak
Eğer intlist [karşı]> ortalama
sonra sonuç := sonuç + 1;
yorum Yazdır sonucu;
printstring("Değerlerin sayısı > ortalama:");
printint (sonuç)
son
Başka
printstring ("Hata—giriş listesi uzunluğu yasal değil";
son
2.6 İş Kayıtlarının Bilgisayarlaştırılması: COBOL
COBOL'un hikayesi bir anlamda ALGOL 60'ın hikayesinin tam tersi.
COBOL, diğer tüm programlama dillerinden daha fazla kullanılmıştır.
PL/I dışında sonraki dillerin tasarımı üzerinde çok az etkisi vardır. Olabilir
5 olduğundan emin olmak zor olsa da hala en yaygın kullanılan dil olmaya devam ediyor.
yol veya diğer. COBOL'un sahip olmasının belki de en önemli nedeni
çok az etki, çok az kişinin iş dünyası için yeni bir dil tasarlama girişiminde bulunmasıdır.
ness uygulamaları ortaya çıktığından beri. Bunun nedeni kısmen COBOL'lerin ne kadar iyi
yetenekleri, uygulama alanının ihtiyaçlarını karşılar. Diğer bir sebep ise büyük
son 30 yılda iş bilişiminde büyüme anlaşması gerçekleşti
küçük işletmeler. Bu işletmelerde çok az yazılım geliştirme yapılmıştır.
yer. Bunun yerine, kullanılan yazılımların çoğu kullanıma hazır paketler olarak satın alınır.
çeşitli genel iş uygulamaları için.
5. 1990'ların sonunda, Y2K sorunuyla ilgili bir çalışmada,
Manhattan'ın 22 mil karelik bölgesinde yaklaşık 800 milyon satır COBOL kullanımdaydı.

Sayfa 80
2.6.1 Tarihsel Arka Plan
COBOL'un başlangıcı, ALGOL 60'ınkine biraz benzer.
dilin, insanlar için bir araya gelen bir komite tarafından tasarlandığını
nispeten kısa süreler. O zaman, 1959'da, iş durumu
hesaplama, birkaç yıl önceki bilimsel hesaplama durumuna benziyordu,
Fortran tasarlanırken. İş uygulamaları için bir derlenmiş dil
katyonlar, FLOW-MATIC, 1957'de uygulanmıştı, ancak
bir üretici, UNIVAC ve o şirketin bilgisayarları için tasarlandı.
Başka bir dil olan AIMACO, ABD Hava Kuvvetleri tarafından kullanılıyordu, ancak
FLOW-MATIC'in sadece küçük bir varyasyonu. IBM bir programlama tasarlamıştı.
iş uygulamaları için dil, COMTRAN (Ticari Tercüman),
ama henüz uygulanmamıştı. Diğer birkaç dil tasarım projesi
planlanıyordu.
2.6.2 AKIŞ-MATİK
FLOW-MATIC'in kökenleri en azından kısa bir tartışmaya değer, çünkü
COBOL'un birincil atasıydı. Aralık 1953'te Grace Hopper
Remington-Rand'da UNIVAC, gerçekten de kehanet niteliğinde bir teklif yazdı.
“Matematiksel programların matematiksel olarak yazılması gerektiğini” önerdi.
notasyonu, veri işleme programları İngilizce ifadelerle yazılmalıdır”
(Wexelblat, 1981, s. 16). Ne yazık ki, 1953'te ikna etmek imkansızdı.
programcı olmayanlar için bir bilgisayarın İngilizce kelimeleri anlayacak şekilde yapılabileceği.
1955 yılına kadar benzer bir teklifin finanse edilme umudu yoktu.
UNIVAC yönetimi tarafından ve o zaman bile bunu yapmak için bir prototip sistem aldı.
son ikna edici. Bu satış sürecinin bir kısmı, bir
küçük bir program, önce İngilizce anahtar kelimeler, ardından Fransızca anahtar kelimeler ve
sonra Almanca anahtar kelimeler kullanarak. Bu gösteri dikkat çekici olarak kabul edildi
UNIVAC yönetimi tarafından ve Hop-
başına teklif.
2.6.3 COBOL Tasarım Süreci
İş dünyası için ortak bir dil konusunda ilk resmi toplantı
Savunma Bakanlığı sponsorluğunda gerçekleştirilen uygulamalar,
28 ve 29 Mayıs 1959'da Pentagon'da (Zürih'ten tam bir yıl sonra)
ALGOL toplantısı). Grubun fikir birliği, dilin, daha sonra
CBL (Common Business Language) olarak adlandırılan, aşağıdaki genel
özellikleri: Çoğu, mümkün olduğunca İngilizce kullanması gerektiği konusunda hemfikirdi,
birkaçı daha matematiksel bir gösterimi savunduysa da. dil gerekir
genişletmek için daha az güçlü olma pahasına bile kullanımı kolay olmalıdır.
bilgisayar programlayabilenlerin temeli. yapılmasının yanı sıra
kullanımı kolay bir dil olduğundan, İngilizce kullanımının insan-
Programları okumak için yaşlılar. Son olarak, tasarım aşırı kısıtlamalarla sınırlandırılmamalıdır.
uygulanmasının sorunları.
2.6 İş Kayıtlarının Bilgisayarlaştırılması: COBOL 59

Sayfa 81
60
Bölüm 2 Başlıca Programlama Dillerinin Evrimi
Toplantıdaki en önemli endişelerden biri, bunu yaratmaya yönelik adımların atılmasıydı.
zaten çok fazla iş yapıldığı için evrensel dil hızlı bir şekilde alınmalıdır.
diğer iş dillerini oluşturmak için yapılır. Mevcut dillere ek olarak,
RCA ve Sylvania kendi iş uygulamaları dilleri üzerinde çalışıyorlardı.
Evrensel bir dil üretmek ne kadar uzun sürerse, o kadar uzun sürdüğü açıktı.
dilin yaygın olarak kullanılması zor olacaktır. Bu temelde,
Mevcut dillerin hızlı bir şekilde incelenmesi gerektiğine karar verildi. Bunun için
görev, Kısa Menzil Komitesi kuruldu.
Dilin ifadelerini ayırmak için erken kararlar vardı.
iki kategori—veri açıklaması ve yürütülebilir işlemler—ve duruma sahip olmak-
Bu iki kategorideki uygulamalar programların farklı bölümlerinde yer alır. Tartışmalardan biri
Kısa Menzilli Komite'nin raporu, aboneliklerin dahil edilmesinin üzerindeydi. Birçok kom-
mittee üyeleri, aboneliklerin verilerdeki insanlar için çok karmaşık olduğunu savundu
matematiksel gösterimden rahatsız olduğu düşünülen işleme.
Benzer argümanlar, aritmetik ifadelerin olması gerekip gerekmediği etrafında dönüyordu.
dahil. Kısa Mesafe Komitesi'nin tamamlanan nihai raporu
Aralık 1959'da, daha sonra COBOL 60 olarak adlandırılan dili tanımladı.
Hükümet tarafından yayınlanan COBOL 60 için dil özellikleri
Nisan 1960'ta Matbaa (Savunma Bakanlığı, 1960),
"ilk" olarak. Gözden geçirilmiş versiyonları 1961 ve 1962'de yayınlandı.
Savunma, 1961, 1962). Dil, Amerikan Ulusal tarafından standartlaştırılmıştır.
1968'de Standartlar Enstitüsü (ANSI) grubu. Sonraki üç revizyon standarttı.
ANSI tarafından 1974, 1985 ve 2002'de geliştirildi. Dil bugün de gelişmeye devam ediyor.
2.6.4 Değerlendirme
COBOL dili bir dizi yeni kavram üretti, bunlardan bazıları
hangi sonunda diğer dillerde ortaya çıktı. Örneğin, DEFINE fiili
COBOL 60, makrolar için ilk yüksek seviyeli dil yapısıydı. Daha
İlk olarak Plan-'da ortaya çıkan önemli, hiyerarşik veri yapıları (kayıtlar)
kalkül, ilk olarak COBOL'da uygulanmıştır. Çoğuna dahil oldular
O zamandan beri tasarlanan zorunlu dillerden. COBOL aynı zamanda ilk
isimlerin gerçekten çağrışımsal olmasına izin veren dil, çünkü her ikisine de izin verdi.
uzun adlar (en fazla 30 karakter) ve sözcük bağlayıcı karakterler (tireler).
Genel olarak, veri bölümü COBOL'un tasarımının güçlü bir parçasıdır, oysa
prosedür bölümü nispeten zayıftır. Her değişken ayrıntılı olarak tanımlanmıştır.
ondalık basamak sayısı ve konumu da dahil olmak üzere veri bölümü
ima edilen ondalık nokta. Dosya kayıtları da bu ayrıntı düzeyiyle tanımlanır,
COBOL'u yazdırma için ideal kılan bir yazıcıya yazdırılacak satırlar gibi
muhasebe raporları. Belki de orijinal pro-
sedure bölümü, işlev eksikliğindeydi. COBOL'un önceki sürümleri
1974 standardı da parametreli alt programlara izin vermiyordu.
COBOL hakkındaki son yorumumuz: İlk programlama diliydi
kullanımı Savunma Bakanlığı (DoD) tarafından zorunlu kılınmıştır. Bu yetki
COBOL özel olarak tasarlanmadığından, ilk geliştirilmesinden sonra geldi.
DoD için çağrı. Avantajlarına rağmen, COBOL muhtemelen

Sayfa 82
bu yetki olmadan hayatta kaldı. Erken derleyicilerin düşük performansı
basitçe dili kullanmak için çok pahalı hale getirdi. Sonunda, elbette, derleyiciler
daha verimli hale geldi ve bilgisayarlar çok daha hızlı ve ucuz hale geldi ve
çok daha büyük anılar. Birlikte, bu faktörler COBOL'un başarılı olmasına izin verdi,
Savunma Bakanlığı'nın içinde ve dışında. Görünüşü, elektronik mekanizasyona yol açtı.
muhasebe, her açıdan önemli bir devrim.
Aşağıda bir COBOL programı örneği verilmiştir. Bu program okur
hakkında envanter bilgilerini içeren BAL-FWD-FILE adlı bir dosya
belirli öğeler koleksiyonu. Diğer şeylerin yanı sıra, her öğe kaydı şunları içerir:
o anda eldeki numara ( ELDE BAL ) ve öğenin yeniden sipariş noktası
( BAL-YENİDEN SİPARİŞ NOKTASI ). Yeniden sipariş noktası, öğelerin eşik sayısıdır
daha fazla sipariş verilmesi gereken elinizin altında. Program bir öğe listesi üretir
REORDER-LISTING adlı bir dosya olarak yeniden sıralanması gerekir .
KİMLİK BÖLÜMÜ.
PROGRAM-ID. ÜRÜN-YENİDEN SİPARİŞ-LİSTELEME.
ÇEVRE BÖLÜMÜ.
KONFİGÜRASYON BÖLÜMÜ.
KAYNAK-BİLGİSAYAR. DEC-VAX.
NESNE-BİLGİSAYAR. DEC-VAX.
GİRİŞ-ÇIKIŞ BÖLÜMÜ.
DOSYA KONTROLÜ.
OKUYUCUYA BAL-FWD-DOSYA ATA SEÇİN.
YENİDEN SİPARİŞ LİSTESİ SEÇİN YEREL YAZICIYA ATAN.
VERİ BÖLÜMÜ.
DOSYA BÖLÜMÜ.
FD BAL-FWD-DOSYA
ETİKET KAYITLARI STANDARTTIR
KAYIT 80 KARAKTER İÇERMEKTEDİR.
01 BAL-FWD-KARTI.
02 BAL-ÜRÜN-NO
RESİM 9(5).
02 BAL-ÖĞE-TANIM RESİM X(20).
02 DOLGU
RESİM X(5).
02 BAL-BİRİM FİYATI RESİM 999V99.
02 BAL-YENİDEN SİPARİŞ NOKTASI RESMİ 9(5).
02 ELDE BAL
RESİM 9(5).
02 SİPARİŞ ÜZERİNDEKİ RESİM 9(5).
02 DOLGU
RESİM X(30).
FD SİPARİŞ LİSTESİ
ETİKET KAYITLARI STANDARTTIR
KAYIT 132 KARAKTER İÇERMEKTEDİR.
01 YENİDEN SİPARİŞ HATTI.
2.6 İş Kayıtlarının Bilgisayarlaştırılması: COBOL 61

Sayfa 83
62
Bölüm 2 Başlıca Programlama Dillerinin Evrimi
02 RL-ÜRÜN-NO
RESİM Z(5).
02 DOLGU
RESİM X(5).
02 RL-ITEM-DESC RESİM X(20).
02 DOLGU
RESİM X(5).
02 RL-BİRİM FİYATI RESİM ZZZ.99.
02 DOLGU
RESİM X(5).
02 RL-MEVCUT-STOK RESİM Z(5)'DİR.
02 DOLGU
RESİM X(5).
02 RL-YENİDEN SİPARİŞ NOKTASI RESİM Z(5)'DİR.
02 DOLGU
RESİM X(71).
ÇALIŞMA-DEPOLAMA BÖLÜMÜ.
01 ANAHTARLAR.
02 KART-EOF-SWITCH RESİM X.
01 ÇALIŞMA ALANLARI.
02 MEVCUT-STOK RESİM 9(5).
PROSEDÜR BÖLÜMÜ.
000-ÜRÜN-YENİDEN SİPARİŞ-LİSTELEME.
AÇIK GİRİŞ BAL-FWD-DOSYA.
AÇIK ÇIKTI YENİDEN SİPARİŞ LİSTESİ.
"N" yi CARD-EOF-SWITCH'E TAŞIYIN.
100-ÜRÜN-YENİDEN SİPARİŞ-HATTINI GERÇEKLEŞTİRİN
KART-EOF-SWITCH "Y" İLE EŞİT OLAN KADAR.
BAL-FWD-DOSYASINI KAPATIN.
YENİDEN SİPARİŞ LİSTESİNİ KAPATIN.
ÇALIŞTIRMAYI DURDUR.
100-ÜRÜN-YENİDEN SİPARİŞ-HATTI.
110-OKUMA-ENVANTER-KAYDI GERÇEKLEŞTİRİN.
CARD-EOF-SWITCH "Y" İLE EŞİT DEĞİLSE]
120-HESAPLA-MEVCUT-STOK GERÇEKLEŞTİRİN
MEVCUT STOK, BAL-YENİDEN SİPARİŞ NOKTASINDAN DAHA AZ ise
130-BASKI-YENİDEN SİPARİŞ-SATIR YAPIN.
110-OKUMA-ENVANTER-KAYDI.
BAL-FWD-DOSYA KAYDI OKUYUN
BİTTİ
"Y" yi CARD-EOF-SWITCH'E TAŞIYIN.
120-HESAPLA-MEVCUT-STOK.
SİPARİŞ ÜZERİNE DENGE EKLE
MEVCUT STOK VERMEK.
130-BASKI-YENİDEN SİPARİŞ-SATIR.
HAREKET ALANI
REORDER-LINE İÇİN.

Sayfa 84
BAL-ITEM-NO'yu RL-ITEM-NO'YA TAŞIYIN.
BAL-ITEM-DESC'İ RL-ITEM-DESC'E TAŞI.
BAL-UNIT-PRICE'ı RL-UNIT-PRICE'A TAŞIYIN.
MEVCUT-STOK'U RL-MEVCUT-STOK'A TAŞIYIN.
BAL-YENİDEN SİPARİŞ NOKTASINI RL-YENİDEN SİPARİŞ NOKTASINA TAŞIYIN.
REORDER-LINE YAZIN.
2.7 Devre Paylaşımın Başlangıcı: TEMEL
BASIC (Mather ve Waite, 1971) başka bir programlama dilidir.
yaygın kullanımdan zevk aldı, ancak çok az saygı gördü. COBOL gibi,
bilgisayar bilimcileri tarafından büyük ölçüde göz ardı edilmiştir. Ayrıca, COBOL gibi,
en eski versiyonlar yetersizdi ve sadece yetersiz bir kontrol seti içeriyordu.
ifadeler.
BASIC, 1970'lerin sonlarında ve başlarında mikrobilgisayarlarda çok popülerdi.
1980'ler. Bu, doğrudan erken dönem edebiyatının iki temel özelliğinden kaynaklanmaktadır.
BASIC'in iyonları. Yeni başlayanlar için, özellikle de yeni başlayanlar için öğrenmesi kolaydı.
bilim odaklı değildir ve daha küçük lehçeleri bilgisayar üzerinde uygulanabilir.
çok küçük anıları olan kişiler. 6 Mikrobilgisayarların yetenekleri büyüdüğünde
ve diğer diller uygulandı, BASIC kullanımı azaldı. Güçlü
BASIC kullanımındaki canlanma, Visual Basic'in ortaya çıkmasıyla başladı.
(Microsoft, 1991) 1990'ların başında.
2.7.1 Tasarım Süreci
BASIC (Yeni Başlayanlar İçin Çok Amaçlı Sembolik Talimat Kodu) orijinal olarak
New Hamp'taki Dartmouth Koleji'nde (şimdi Dartmouth Üniversitesi) tasarlandı.
shire adlı iki matematikçi, John Kemeny ve Thomas Kurtz tarafından
1960'ların başında, Fortran'ın çeşitli lehçeleri için derleyiciler geliştirdi ve
ALGOL 60. Fen bilimleri öğrencileri genellikle öğrenmede çok az sorun yaşadılar veya
çalışmalarında bu dilleri kullanmak. Bununla birlikte, Dartmouth öncelikle bir
bilim ve mühendislik öğrencilerinin sadece oluşturduğu liberal sanatlar kurumu
öğrenci vücudunun yaklaşık yüzde 25'i. 1963 baharında karar verildi.
özellikle liberal sanat öğrencileri için yeni bir dil tasarlayın. Bu yeni dil
bilgisayar erişim yöntemi olarak terminalleri kullanırdı. Sistemin hedefleri
şöyleydi:
1. Bilim dışı öğrencilerin öğrenmesi ve kullanması kolay olmalıdır.
2. “Hoş ve arkadaş canlısı” olmalıdır.
3. Ödev için hızlı geri dönüş sağlamalıdır.
6. Bazı ilk mikrobilgisayarlar, 4096 baytlık BASIC yorumlayıcılarını içeriyordu.
ROM.
2.7 Devre Paylaşımın Başlangıcı: BASIC 63

Sayfa 85
64
Bölüm 2 Başlıca Programlama Dillerinin Evrimi
4. Ücretsiz ve özel erişime izin vermelidir.
5. Kullanıcı zamanını bilgisayar zamanından daha önemli saymalıdır.
Son hedef gerçekten de devrimci bir kavramdı. En azından kısmen dayanıyordu
bilgisayarların zaman geçtikçe önemli ölçüde daha ucuz hale geleceği inancı üzerine
üzerinde, tabii ki yaptılar.
İkinci, üçüncü ve dördüncü gollerin kombinasyonu zaman-
BASIC'in paylaşılan yönü. Sadece terminaller aracılığıyla bireysel erişim ile
çok sayıda eşzamanlı kullanıcı bu hedeflere 1960'ların başında ulaşabildi.
1963 yazında, Kemeny ilk derleyici için çalışmaya başladı.
GE 225 bilgisayarına uzaktan erişim kullanan BASIC sürümü. Dizayn ve
BASIC için işletim sisteminin kodlanması 1963 sonbaharında başladı.
Bir . M . 1 Mayıs 1964'te devre paylaşımlı BASIC'i kullanan ilk program yazıldı.
içeri ve çalıştırın. Haziran ayında sistemdeki terminal sayısı 11'e yükseldi.
düşüş 20'ye yükseldi.
2.7.2 Dile Genel Bakış
BASIC'in orijinal versiyonu çok küçüktü ve garip bir şekilde etkileşimli değildi:
Yürütülen bir programın kullanıcıdan girdi verisi almasının hiçbir yolu yoktu.
Programlar, bir tür toplu iş odaklı şekilde yazıldı, derlendi ve çalıştırıldı.
Orijinal BASIC yalnızca 14 farklı ifade tipine ve tek bir veriye sahipti.
type—kayan nokta. Çünkü hedeflenen kullanıcıların çok azının
tamsayı ve kayan nokta türleri arasındaki farkı takdir edecek,
türü “sayılar” olarak anılırdı. Genel olarak, çok sınırlı bir dildi,
öğrenmesi oldukça kolay olsa da.
2.7.3 Değerlendirme
Orijinal BASIC'in en önemli yönü, ilk olmasıydı.
bir uzaktan kumandaya bağlı terminaller aracılığıyla kullanılan yaygın olarak kullanılan dil
bilgisayar. O zamanlar 7 Terminal daha yeni hizmete girmeye başlamıştı. Bundan önce,
çoğu program bilgisayarlara delikli kartlar veya
kağıt bant.
BASIC'in tasarımının çoğu, bazı küçük etkilerle birlikte Fortran'dan geldi.
ALGOL 60'ın söz diziminden türetilmiştir. Daha sonra çeşitli şekillerde büyümüştür.
standart hale getirmek için çok az çaba harcandı veya hiç çaba gösterilmedi. Amerikan Ulusal Standartları
Enstitü bir Minimal BASIC standardı yayınladı (ANSI, 1978b), ancak bu
sadece minimum dil özellikleri. Aslında, orijinal BASIC
Minimal BASIC'e çok benzer.
Şaşırtıcı görünse de Digital Equipment Corporation,
önemli yazmak için BASIC-PLUS adlı BASIC'in oldukça ayrıntılı versiyonu
7. LISP başlangıçta terminaller aracılığıyla kullanıldı, ancak 1960'ların başında yaygın olarak kullanılmadı.

Sayfa 86
PDP-11 mini bilgisayarlar için en büyük işletim sistemlerinin bazı bölümleri,
RSTS, 1970'lerde.
BASIC, yazılı programların zayıf yapısı nedeniyle eleştirilmiştir.
o, diğer şeylerin yanı sıra. Bölüm 1'de tartışılan değerlendirme kriterlerine göre, özel
açıkça okunabilirlik ve güvenilirlik, dil gerçekten de çok kötü gidiyor.
Açıkça, dilin ilk versiyonları amaçlanmamıştır ve olmamalıdır.
önemli boyuttaki ciddi programlar için kullanılmıştır. sonraki sürümler
bu tür görevlere çok daha uygundur.
BASIC'in 1990'larda yeniden canlanması,
Görsel BASIC (VB). VB sağladığı için büyük ölçüde yaygın olarak kullanılmaya başlandı.
grafik kullanıcı arabirimleri (GUI'ler) oluşturmanın basit bir yolu, dolayısıyla adı
Visual Basic. Visual Basic .NET veya sadece VB.NET, Microsoft'un .NET'lerinden biridir.
Diller. VB'den önemli bir sapma olmasına rağmen, hızla yer değiştirdi
eski dil. VB ve arasındaki belki de en önemli fark
VB.NET, VB.NET'in nesne yönelimli programlamayı tamamen desteklemesidir.
Aşağıda bir BASIC programı örneği verilmiştir:
REM BASIC Örnek Program
REM Girişi: listlen'in daha az olduğu bir tamsayı, listlen
REM
100'den fazla, ardından listlen-integer değerleri
REM Çıkışı: Daha büyük olan giriş değerlerinin sayısı
REM
tüm girdi değerlerinin ortalamasından
DIM dahili listesi(99)
sonuç = 0
toplam = 0
GİRİŞ listesi
IF listlen > 0 VE listlen < 100 THEN
REM Bir diziye girişi okuyun ve toplamı hesaplayın
Sayaç için = 1 Dinlemek için
GİRİŞ intlist(sayaç)
toplam = toplam + iç liste(sayaç)
SONRAKİ sayaç
REM Ortalamayı hesapla
ortalama = toplam / dinle
REM > ortalama olan giriş değerlerinin sayısını sayın
Sayaç için = 1 Dinlemek için
IF iç listesi(sayaç) > ortalama
SONRA sonuç = sonuç + 1
SONRAKİ sayaç
REM Sonucu yazdır
PRINT "> ortalama olan değerlerin sayısı:";
sonuç
BAŞKA
PRINT "Hata—giriş listesi uzunluğu yasal değil"
EĞER SON
SON
2.7 Devre Paylaşımın Başlangıcı: TEMEL 65

Sayfa 87
röportaj yapmak
Kullanıcı Tasarımı ve Dil Tasarımı
ALAN COOPER
About Face: The Essentials of User Interface Design kitabının en çok satan yazarı, Alan
Cooper'ın ayrıca, dil olarak lanse edilebilecek olanı tasarlamada büyük bir eli vardı.
Kullanıcı arayüzü tasarımı için en çok endişe duyulan şey Visual Basic. Onun için her şey düşüyor
teknolojiyi insancıllaştırmak için bir vizyona.
TEMEL BİLGİLER HAKKINDA BAZI BİLGİLER
Tüm bunlara nasıl başladınız? ben yüksek
programda önlisans derecesi ile okulu bırakma-
California toplum kolejinden Ming. İlk işim
American President Lines için programcıydı
(Amerika Birleşik Devletleri'nin en eski okyanus taşımacılığından biri
şirketleri) San Francisco'da. Birkaç ay hariç
burada ve orada, serbest meslek sahibi olarak kaldım.
Şu anki mesleğin nedir? Kurucu ve başkan
teknolojiyi insanlaştıran şirket Cooper'ın
( www.cooper.com).
En sevdiğiniz iş nedir veya neydi? Etkileşim
tasarım danışmanı.
lan alanlarında çok iyi tanınıyorsunuz.
guage tasarımı ve kullanıcı arayüzü tasarımı. Herhangi
tasarım dillerine karşı tasarım üzerine düşünceler-
yazılım tasarlamak mı, başka bir şey tasarlamak mı? Onun
yazılım dünyasında hemen hemen aynı: Bilin
kullanıcınız.
ERKEN WINDOWS YAYINLANMASI HAKKINDA
1980'lerde Windows'u kullanmaya başladınız ve
artıları tarafından cezbedilmekten bahsetti:
grafiksel kullanıcı arayüzü desteği ve dinami-
araçlar oluşturmanıza izin veren tam olarak bağlantılı kitaplık
kendilerini yapılandırdılar. peki ya bölümleri
Sonunda şekillenmesine yardımcı olduğunuz Windows? ben ... idim
Microsoft'un desteği dahil etmesinden çok etkilendim
Windows'ta pratik çoklu görev için. Bu dahil
dinamik yer değiştirme ve süreçler arası iletişim.
MSDOS.exe, ilk birkaçı için kabuk programıydı.
Windows sürümleri. Berbat bir programdı ve ben
önemli ölçüde geliştirilebileceğine inandım ve ben
yapacak adamdı. Boş zamanlarımda hemen
birinden daha iyi bir kabuk programı yazmaya başladı
Windows ile geldi. Adını Tripod koydum. Microsoft'un
orijinal kabuk, MSDOS.exe, ana güdülerden biriydi.
bling, Windows'un ilk başarısını engeller. tripod
kullanımı daha kolay hale getirerek sorunu çözmeye çalıştı
ve yapılandırmak için.
Ne zaman "Hah!" an? o zamana kadar değildi
1987 yılının sonlarında, kurumsal bir müşteriyle röportaj yaparken
Tripod için anahtar tasarım stratejisi ortaya çıktı
kafam. IS yöneticisinin bana ihtiyacını açıkladığı gibi
çok çeşitli kabuk çözümleri oluşturmak ve yayınlamak için
farklı kullanıcı tabanına, bilmeceyi fark ettim
ideal kabuk diye bir şey yoktur. her kullanıcı
kendilerine göre yapılandırılmış kendi kişisel kabuklarına ihtiyaç duyacaktır.
kendi ihtiyaçları ve beceri seviyeleri. Bir anda algıladım
kabuk tasarım sorununa çözüm: Bir kabuk olurdu
inşaat seti; her kullanıcının yapabileceği bir araç
tam olarak ihtiyaç duyduğu kabuğu inşa etmek
benzersiz bir uygulama ve eğitim karışımı.
Bir kabuk fikri hakkında bu kadar çekici olan nedir?
kişiselleştirilebilir mi? Ben anlatmak yerine
Kullanıcılar ideal kabuğun ne olduğunu tasarlayabilirlerdi
kendi, kişiselleştirilmiş ideal kabuğu. bir özelleştirme ile-
yetenekli bir kabuk, bir programcı bir kabuk yaratacaktır.
güçlü ve geniş kapsamlı ama aynı zamanda biraz tehlikeli-
bir BT yöneticisi bir kabuk yaratırken,
sadece bunları ifşa eden bir masa memuruna verilebilir.
memurun kullandığı birkaç uygulamaya özel araç.
66

Sayfa 88
yazıdan nasıl anladın
işbirliği yapmak için bir kabuk programı
Microsoft ile derecelendirme? tripod
ve Ruby aynı şeydir.
Bill ile bir anlaşma imzaladıktan sonra
Gates, adını değiştirdim
Tripod'dan prototipe
Yakut. Daha sonra Ruby'yi kullandım
prototiplerin olması gerektiği gibi prototip
kullanılabilir: tek kullanımlık bir model olarak
sürüm kalitesi oluşturmak için
kod. Ben ne yaptım. MS yayın sürümünü aldı
Ruby ve QuickBASIC'i ekleyerek VB'yi yarattı. Herşey
Bu orijinal yeniliklerden bazıları Tripod/Ruby'deydi.
GÖRSEL TEMEL İÇİN KÜVATÖR OLARAK RUBY
Erken Windows'a olan ilginizi tekrar gözden geçirelim ve
bu DLL özelliği. DLL bir şey değildi, bir
işletim sistemindeki tesis. Bir programcının inşa etmesine izin verdi
çalışma zamanında şu şekilde bağlanabilecek kod nesneleri
yalnızca derleme zamanında karşıt. izin verilen bu
VB'nin dinamik olarak genişletilebilir kısımlarını icat etmem için,
üçüncü taraf satıcılar tarafından kontrollerin eklenebileceği yerler.
Ruby ürünü birçok önemli ürünü bünyesinde barındırıyor.
yazılım tasarımındaki ilerlemeler, ancak ikisi ayakta
son derece başarılı olarak çıktı. Bahsettiğim gibi,
Windows'un dinamik bağlantı yeteneği her zaman
ilgimi çekti, ama araçlara sahip olmak ve ne olduğunu bilmek
onlarla yapmak iki farklı şeydi. Ruby ile,
Sonunda dinamik bağlantı için iki pratik kullanım buldum,
ve orijinal program her ikisini de içeriyordu. İlk önce
dil hem kurulabilir hem de genişletilebilirdi
dinamik olarak. İkincisi, gizmos paleti olabilir
dinamik olarak eklendi.
Ruby'de sizin diliniz ilk kez mi kullanıldı?
dinamik bağlantılı kitaplık ve bir
görsel ön uç? Bildiğim kadarıyla, evet.
Basit bir örnek kullanarak, bu neyi mümkün kılar?
programcı kendi programıyla ne yapacak? pur-
şebeke kontrolü gibi bir kontrolü üçüncü bir
parti satıcısı, kendi bilgisayarına kurun ve
şebeke kontrolü, şebekenin ayrılmaz bir parçası olarak görünür.
görsel programlama ön ucu dahil olmak üzere guage.
Sana neden “Görselin Babası” diyorlar?
Temel"? Ruby küçük bir dille geldi, biri uygun
sadece bir düzine kadar basit komutu yürütmek için
bir kabuk programının ihtiyaç duyduğu şey. Ancak bu dil,
herhangi bir sayıda olan bir DLL zinciri olarak uygulanır.
çalışma zamanında kurulabilir. Dahili ayrıştırıcı
bir fiili tanımlar ve sonra onu zincir boyunca iletirdi
biri bildiğini kabul edene kadar DLL'lerin
fiil nasıl işlenir. Tüm DLL'ler geçtiyse,
bir sözdizimi hatası vardı. İlk tartışmalarımızdan,
hem Microsoft hem de ben büyüme fikrini eğlendirmiştik.
dili kullanmak, hatta muhtemelen onu tamamen değiştirmek
“gerçek” bir dille. C en çok adaydı
sık sık bahsedildi, ancak sonunda Microsoft
fişini çekmek için bu dinamik arayüzün avantajı
küçük kabuk dili ve tamamen Quick- ile değiştirin.
TEMEL. Dilin görsel cepheyle olan bu yeni evliliği
sonu statik ve kalıcıydı ve kökeni
nal dinamik arayüz, bağlantıyı mümkün kıldı,
süreçte kaybedildi.
YENİ FİKİRLER ÜZERİNE BAZI SON YORUMLAR
Programlama ve programlama dünyasında
diller ve ortamlar dahil olmak üzere araçlar,
en çok hangi projeler ilgini çekiyor? İlgiliyim
yardımcı olmak için tasarlanmış programlama araçları oluşturmak
Programcılar yerine kullanıcılar.
En kritik kural, ünlü alıntı nedir veya
akılda tutulması gereken tasarım fikri? Köprüler yapılmadı
mühendisler tarafından. Demirciler tarafından inşa edilirler.
Benzer şekilde, yazılım programları mühendisler tarafından oluşturulmaz.
neerler Programcılar tarafından oluşturulurlar.
MSDOS.exe ilk birkaçı için kabuk programıydı.
Windows sürümleri. Korkunç bir programdı ve
Önemli ölçüde geliştirilebileceğine inandım,
ve bunu yapacak adam bendim. Boş zamanlarımda ben
hemen daha iyi bir kabuk programı yazmaya başladı
Windows ile birlikte gelenden daha fazla.
67

Sayfa 89
68
Bölüm 2 Başlıca Programlama Dillerinin Evrimi
2.8 Herkes İçin Her Şey: PL/I
PL/I, bir dil tasarlamaya yönelik ilk büyük ölçekli girişimi temsil eder.
geniş bir uygulama alanı yelpazesi için kullanılabilir. Tüm önceki ve çoğu alt
sıralı diller, belirli bir uygulama alanına odaklanmıştır, örneğin
bilim, yapay zeka veya iş.
2.8.1 Tarihsel Arkaplan
Fortran gibi, PL/I bir IBM ürünü olarak geliştirildi. 1960'ların başına gelindiğinde,
endüstrideki bilgisayar kullanıcıları iki ayrı ve oldukça farklı
ateşli kamplar: bilimsel ve ticari. IBM açısından, bilimsel
programcılar, büyük ölçekli 7090 veya küçük ölçekli 1620 IBM'i kullanabilir
bilgisayarlar. Bu grup, kayan nokta verilerini ve dizileri yoğun bir şekilde kullandı. Fortran
birincil dildi, ancak bazı montaj dili de kullanılıyordu.
Kendi kullanıcı grupları olan SHARE'leri vardı ve kimseyle çok az temasları vardı.
kim iş uygulamaları üzerinde çalıştı.
İş uygulamaları için insanlar büyük 7080 veya küçük 1401'i kullandılar.
IBM bilgisayarlar. Ondalık ve karakter dizisi veri türlerine ihtiyaçları vardı.
ayrıntılı ve verimli girdi ve çıktı tesislerinin yanı sıra. COBOL kullandılar,
PL/I hikayesinin başladığı 1963 yılının başlarında olsa da, montajdan dönüşüm
COBOL'un dili tam olmaktan çok uzaktı. Bu kullanıcı kategorisi ayrıca
kendi kullanıcı grubu, GUIDE'ı vardı ve nadiren bilimsel kullanıcılarla iletişim kurdu.
1963'ün başlarında, IBM planlamacıları bu konuda bir değişikliğin başlangıcını algıladılar.
durum. Birbirinden geniş ölçüde ayrılmış iki bilgisayar kullanıcı grubu,
sorun yaratacağı kesin olarak düşünülen şekillerde birbirlerini Bilim insanları
işlenecek büyük veri dosyalarını toplamaya başladı. Bu veriler daha fazlasını gerektiriyordu
gelişmiş ve daha verimli girdi ve çıktı tesisleri. İş uygulaması-
insanlar yönetim bilgilerini oluşturmak için regresyon analizini kullanmaya başladı
kayan nokta verileri ve diziler gerektiren sistemler. öyle görünmeye başladı
bilgi işlem kurulumları yakında iki ayrı bilgisayar ve teknoloji gerektirecektir.
cal staffs, çok farklı iki programlama dilini destekliyor. 8
Bu algılar doğal olarak tek bir evren tasarlama kavramına yol açtı.
hem kayan nokta hem de ondalık sayı yapabilen bilgisayar
aritmetik ve dolayısıyla hem bilimsel hem de ticari uygulamalar. Böylece
IBM System/360 bilgisayar serisi konseptini doğdu. Bununla birlikte
hem iş için kullanılabilecek bir programlama dili fikri geldi
ve bilimsel uygulamalar. İyi bir önlem için, sistem pro-
dilbilgisi ve liste işleme atıldı. Bu nedenle, yeni dil
Fortran, COBOL, LISP ve montaj sistem uygulamalarını değiştirmek
dilim.
8. O zamanlar, büyük bilgisayar kurulumları hem tam zamanlı donanım hem de tam zamanlı sistem gerektiriyordu.
tem yazılım bakım personeli.

sayfa 90
2.8.2 Tasarım Süreci
Tasarım çabası, IBM ve SHARE, Advanced Lan-
Ekim ayında SHARE Fortran Projesi'nin Guage Geliştirme Komitesi
1963. Bu yeni komite hızla bir araya geldi ve bir alt komite kurdu.
3 × 3 Komite, IBM'den üç üyesi ve üç üyesi olduğu için bu şekilde adlandırılmıştır.
SHARE'den. 3 × 3 Komite, üç veya dört gün arayla toplandı
dili tasarlamak için hafta.
COBOL için Kısa Mesafe Komitesinde olduğu gibi, ilk tasarım şu şekildeydi:
oldukça kısa bir sürede tamamlanması planlanmaktadır. Görünüşe bakılırsa,
Bir dil tasarımı çabasının kapsamında, 1960'ların başında hakim olan inanç
üç ayda yapılabilmesiydi. PL/I'nin ilk versiyonu olan
daha sonra Fortran VI olarak adlandırıldı, Aralık ayına kadar tamamlanması gerekiyordu, daha az
komite kurulduktan üç ay sonra. Komite yalvardı
uzatmalar için iki farklı durumda başarılı bir şekilde, son tarihi geri alarak
Ocak ayına ve daha sonra 1964 Şubatının sonlarına kadar.
İlk tasarım konsepti, yeni dilin bir uzantı olacağıydı.
Fortran IV'ün sürümü, uyumluluğu korudu, ancak bu hedef düştü
Fortran VI adıyla birlikte hızlı bir şekilde. 1965 yılına kadar dil biliniyordu.
NPL (Yeni Programlama Dili) olarak. NPL hakkında yayınlanan ilk rapor
Mart 1964'teki SHARE toplantısında verildi.
Nisan ayında takip edildi ve gerçekte uygulanacak olan sürüm
Aralık 1964'te (IBM, 1964) derleyici grubu tarafından yayınlanmıştır.
Uygulamayı yapmak için seçilen İngiltere'deki IBM Hursley Laboratuvarı,
mental aktivite. 1965 yılında, karışıklığı önlemek için isim PL/I olarak değiştirildi.
NPL adını İngiltere'deki Ulusal Fizik Laboratuvarı ile birlikte aldı. Eğer
derleyici Birleşik Krallık dışında geliştirilmişti, adı
NPL kalmıştır.
2.8.3 Dile Genel Bakış
PL/I'nin belki de en iyi tek cümlelik açıklaması, içerdiği şeyleri içermesidir.
daha sonra ALGOL 60'ın en iyi parçaları olarak kabul edildi (özyineleme ve blok yapısı)
ture), Fortran IV (küresel aracılığıyla iletişim ile ayrı derleme
veri) ve COBOL 60 (veri yapıları, girdi/çıktı ve rapor oluşturma
tesisler), geniş bir yeni yapı koleksiyonuyla birlikte, hepsi bir şekilde
hepsini bir araya topla. PL/I artık popüler bir dil olmadığı için,
kısaca, dilin tüm özelliklerini, hatta dilini tartışmaya çalışın.
en tartışmalı yapılar. Bunun yerine, bazı lan-
guage'nin programlama dilleri bilgi havuzuna katkıları.
PL/I, aşağıdaki olanaklara sahip ilk programlama diliydi:
• Programların aynı anda çalışan alt programlar oluşturmasına izin verildi.
Bu iyi bir fikir olmasına rağmen, PL/I'de zayıf bir şekilde geliştirildi.
• 23 farklı istisna türünü tespit etmek ve işlemek mümkündü veya
çalışma zamanı hataları.
2.8 Herkes İçin Her Şey: PL/I 69

Sayfa 91
70
Bölüm 2 Başlıca Programlama Dillerinin Evrimi
• Alt programların yinelemeli olarak kullanılmasına izin verildi, ancak yetenek
devre dışı bırakılarak özyinelemeli olmayan alt programlar için daha verimli bağlantı sağlanır.
• Veri türü olarak işaretçiler eklendi.
• Dizilerin kesitlerine başvurulabilir. Örneğin, üçüncü satır
bir matris, tek boyutlu bir diziymiş gibi referans alınabilir.
2.8.4 Değerlendirme
PL/I'nin herhangi bir değerlendirmesi, projenin iddialılığını kabul ederek başlamalıdır.
tasarım çabası. Geriye dönüp bakıldığında, bu kadar çok yapının olduğunu düşünmek safça görünüyor.
başarıyla birleştirilebilirdi. Ancak, bu yargı geçici olmalıdır.
çok az dil tasarımı deneyimi olduğunu kabul ederek
zaman. Genel olarak, PL/I tasarımı, herhangi bir yapının
yararlı olan ve uygulanabilecek olan, yetersiz olmakla birlikte dahil edilmelidir.
Bir programcının nasıl anlayabileceği ve etkili bir şekilde kullanabileceği ile ilgili endişe
böyle bir yapı ve özellik koleksiyonundan. Edsger Dijkstra, Turing'inde
Ödül Dersi (Dijkstra, 1972), en güçlü eleştirilerden birini yaptı.
PL/I'nin karmaşıklığı: “Büyümemizi nasıl sürdürebileceğimizi kesinlikle göremiyorum.
katıksız barokluğu ile entelektüel tutuşumuz içinde sıkı bir şekilde programlar
programlama dili - temel aracımız, dikkat edin! - zaten bizden kaçıyor
entelektüel kontrol."
Büyük boyutundan kaynaklanan karmaşıklık sorununa ek olarak, PL/I
şu anda kötü tasarlanmış olduğu düşünülen bir dizi şeyden muzdarip
yapılar. Bunlar arasında işaretçiler, istisna işleme ve eşzamanlılık vardı.
Her durumda, bu yapıların ortaya çıkmadığını belirtmemiz gerekse de
önceki herhangi bir dilde.
Kullanım açısından, PL/I en azından kısmi bir başarı olarak kabul edilmelidir. İçinde
1970'lerde, hem ticari hem de bilimsel uygulamalarda önemli bir kullanımdan yararlandı. o
o dönemde kolejlerde bir öğretim aracı olarak da yaygın olarak kullanıldı,
öncelikle PL/C (Cornell, 1977) ve PL/CS gibi çeşitli alt küme formlarında
(Conway ve Constable, 1976).
Aşağıda bir PL/I programı örneği verilmiştir:
/* PL/I PROGRAM ÖRNEĞİ
GİRİŞ: LISTLEN'İN KÜÇÜK OLDUĞU BİR TAM SAYI, LISTLEN
100, LISTLEN-INTEGER DEĞERLERİ TARAFINDAN TAKİP EDİLİR
ÇIKTI: BÜYÜK GİRDİ DEĞERLERİ SAYISI
TÜM GİRİŞ DEĞERLERİNİN ORTALAMASI */
PLIEX: PROSEDÜR SEÇENEKLERİ (ANA);
DECLARE INTLIST (1:99) DÜZELTİLDİ.
BİLDİRİM (LİSTELENEN, SAYAÇ, TOPLA, ORTALAMA, SONUÇ) SABİT;
TOPLA = 0;
SONUÇ = 0;
LİSTE AL (LİSTELEN);
EĞER (LISTLEN > 0) & (LISTLEN < 100) SONRA

Sayfa 92
YAPMAK;
/* GİRİŞ VERİLERİNİ BİR DİZİYE OKUYUN VE TOPLAMI HESAPLAYIN */
SAYAÇ YAPMAK = 1 DİNLEMEK İÇİN;
LİSTEYİ AL (INTLIST (SAYAÇ));
TOPLA = TOPLA + INTLIST (COUNTER);
SON;
/* ORTALAMANIN HESAPLANMASI */
ORTALAMA = TOPLA / LİSTELENEN;
/* > ORTALAMA OLAN DEĞERLERİN SAYISI */
SAYAÇ YAPMAK = 1 DİNLEMEK İÇİN;
IF INTLIST (COUNTER) > ORTALAMA SONRA
SONUÇ = SONUÇ + 1;
SON;
/* YAZDIRMA SONUCU */
ATLAMA LİSTESİ PUT ('DEĞER SAYISI > ORTALAMA:');
PUT LİSTESİ (SONUÇ);
SON;
BAŞKA
LİSTEYİ ATLA ('HATA—GİRDİ LİSTESİ UZUNLUĞU GEÇERSİZDİR');
SON PLIEX;
2.9 İki Erken Dinamik Dil: APL ve SNOBOL
Bu bölümün yapısı diğer bölümlerden farklıdır çünkü
burada tartışılan diller çok farklı. Ne APL ne de SNOBOL
sonraki ana akım diller üzerinde çok etkisi oldu. 9 İlginç olanlardan bazıları
APL'nin özellikleri kitabın ilerleyen bölümlerinde tartışılacaktır.
Görünüş ve amaç olarak APL ve SNOBOL oldukça farklıdır.
Bununla birlikte, iki temel özelliği paylaşırlar: dinamik yazma ve
dinamik depolama tahsisi. Her iki dilde de değişkenler esasen tipsizdir.
Bir değişken, kendisine bir değer atandığında bir tür elde eder ve bu sırada
atanan değerin türü. Depolama, yalnızca bir değişkene
bir değer atanır, çünkü bundan önce miktarını bilmenin bir yolu yoktur.
ihtiyaç duyulacak depolama.
2.9.1 APL'nin Kökenleri ve Özellikleri
APL (Brown ve diğerleri, 1988) 1960 civarında Kenneth E. Iverson tarafından
IBM. Başlangıçta uygulanan bir programlama dili olarak tasarlanmamıştır.
daha ziyade bilgisayar mimarisini tanımlamak için bir araç olması amaçlandı.
9. Bununla birlikte, bazı ana akım olmayan diller üzerinde bir miktar etkileri vardır (J, APL'ye dayalıdır,
ICON, SNOBOL'u temel alır ve AWK, kısmen SNOBOL'u temel alır).
2.9 İki Erken Dinamik Dil: APL ve SNOBOL 71

Sayfa 93
72
Bölüm 2 Başlıca Programlama Dillerinin Evrimi
APL ilk olarak adını aldığı A Programming kitabında tanımlanmıştır.
Dil (Iverson, 1962). 1960'ların ortalarında, APL'nin ilk uygulaması
IBM'de geliştirildi.
APL, bir ile belirtilen çok sayıda güçlü operatöre sahiptir.
uygulayıcılar için bir sorun oluşturan çok sayıda sembol. İlk olarak,
APL, IBM baskı terminalleri aracılığıyla kullanıldı. Bu terminaller özel
dilin gerektirdiği tek karakter kümesini sağlayan topları yazdırın. Bir
APL'nin bu kadar çok operatöre sahip olmasının nedeni, çok sayıda birim sağlamasıdır.
diziler üzerinde işlemler. Örneğin, herhangi bir matrisin devrik a ile yapılır.
tek operatör Geniş operatör koleksiyonu, çok yüksek ifade sağlar.
değil, aynı zamanda APL programlarının okunmasını da zorlaştırır. Bu nedenle insanların aklına
APL, "kullan-at" programlama için en iyi kullanılan bir dildir. Rağmen
programlar hızlı bir şekilde yazılabilir, kullanımdan sonra atılmalıdır çünkü
bakımları zordur.
APL yaklaşık 50 yıldır var ve bugün hala kullanılıyor.
geniş değil. Ayrıca, ömrü boyunca çok fazla değişmedi.
2.9.2 SNOBOL'un Kökenleri ve Özellikleri
SNOBOL ("kartopu" olarak telaffuz edilir; Griswold ve diğerleri, 1971)
1960'ların başında Bell Laboratuvarlarında üç kişi tarafından: DJ Farber, RE Griswold,
ve IP Polonsky (Farber ve diğerleri, 1964). Metin için özel olarak tasarlanmıştır
işleme. SNOBOL'un kalbi, aşağıdakiler için güçlü işlemlerden oluşan bir koleksiyondur.
dize desen eşleştirme. SNOBOL'un ilk uygulamalarından biri,
metin editörleri yazma. SNOBOL'un dinamik doğası onu yavaşlattığı için
alternatif dillerden daha fazla, artık bu tür programlar için kullanılmamaktadır. Ancak,
SNOBOL, çeşitli diller için kullanılan hala canlı ve desteklenen bir dildir.
birkaç farklı uygulama alanında metin işleme görevleri.
2.10 Veri Soyutlamanın Başlangıcı: SIMULA 67
SIMULA 67 hiçbir zaman yaygın kullanıma ulaşmamış ve üzerinde çok az etkisi olmasına rağmen
zamanının programcıları ve hesaplaması, tanıttığı bazı yapılar
neden olması onu tarihsel olarak önemli kılmaktadır.
2.10.1 Tasarım Süreci
İki Norveçli, Kristen Nygaard ve Ole-Johan Dahl, lan-
SIMULA I, 1962 ve 1964 arasında Norveç Bilgi İşlem Merkezinde
ter (NCC) Oslo'da. Öncelikli olarak bilgisayarları şu amaçlarla kullanmakla ilgilendiler:
simülasyon değil, aynı zamanda yöneylem araştırmasında da çalıştı. SIMULA I tasarlandı
sadece sistem simülasyonu için ve ilk olarak 1964'ün sonlarında bir
UNIVAC 1107 bilgisayar.

Sayfa 94
SIMULA I uygulaması tamamlanır tamamlanmaz, Nygaard ve
Dahl, yeni özellikler ekleyerek ve değiştirerek dili genişletme çabalarına başladı.
dili genel kullanım için yararlı kılmak için bazı mevcut yapıları
amaçlı uygulamalar. Bu çalışmanın sonucu, tasarımı olan SIMULA 67 oldu.
ilk kez Mart 1967'de halka sunuldu (Dahl ve Nygaard, 1967). Yapacağız
SIMULA'nın ilgi çekici özelliklerinden bazıları olmasına rağmen, yalnızca SIMULA 67'yi tartışın
67'si de SIMULA I'dedir.
2.10.2 Dile Genel Bakış
SIMULA 67, ALGOL 60'ın hem blok yapısını hem de
bu dilden kontrol ifadeleri. ALGOL 60'ın birincil eksikliği
(ve o zamanki diğer diller) simülasyon uygulamaları için
onun alt programları. Simülasyon, yeniden başlatılmasına izin verilen alt programlar gerektirir
daha önce durdukları konumda. Bu tür alt programlar
kontrol , arayan ve alt programlar olarak adlandırıldığı için eşyordamlar olarak bilinir.
katı olmaktan ziyade birbirleriyle biraz eşit bir ilişkiye sahip
çoğu zorunlu dilde sahip oldukları efendi/köle ilişkisi.
SIMULA 67'de eşyordamlara destek sağlamak için sınıf yapısı şu şekildeydi:
gelişmiş. Bu önemli bir gelişmeydi çünkü veri kavramı
soyutlama onunla başladı. Ayrıca, veri soyutlama temel sağlar.
nesne yönelimli programlama için
Veri soyutlamanın önemli kavramının
Hoare, 1972 yılına kadar geliştirilmedi ve sınıf yapısına atfedildi.
(1972) bağlantıyı tanıdı.
2.11 Ortogonal Tasarım: ALGOL 68
ALGOL 68, dil tasarımında birkaç yeni fikrin kaynağıydı, bazıları
daha sonra diğer diller tarafından benimsenmiştir. için buraya dahil ediyoruz
bu nedenle, ne Avrupa'da ne de Avrupa'da yaygın bir kullanıma sahip olmasa da,
Birleşik Devletler.
2.11.1 Tasarım Süreci
ALGOL ailesinin gelişimi, revize edilen raporla sona ermedi.
ALGOL 60'ta, bir sonraki tasarıma altı yıl olmasına rağmen, 1962'de ortaya çıktı.
iterasyon yayınlandı. Ortaya çıkan dil, ALGOL 68 (van Wijngaarden
ve diğerleri, 1969), öncekinden önemli ölçüde farklıydı.
ALGOL 68'in en ilginç yeniliklerinden biri,
mary tasarım kriterleri: diklik. Ortogonallik tartışmamızı hatırlayın.
Bölüm 1. Ortogonalliğin kullanımı, çeşitli yenilikçi özelliklerle sonuçlandı.
ALGOL 68, bunlardan biri aşağıdaki bölümde açıklanmıştır.
2.11 Ortogonal Tasarım: ALGOL 68 73

Sayfa 95
74
Bölüm 2 Başlıca Programlama Dillerinin Evrimi
2.11.2 Dile Genel Bakış
ALGOL 68'deki ortogonalliğin önemli bir sonucu, kullanıcı-
tanımlanmış veri türleri Fortran gibi daha önceki diller yalnızca birkaç temel dil içeriyordu.
veri yapıları. PL/I daha fazla sayıda veri yapısı içeriyordu, bu da
öğrenmesi daha zor ve uygulaması zor, ama açıkçası sağlayamadı
her ihtiyaca uygun bir veri yapısı.
ALGOL 68'in veri yapılarına yaklaşımı, birkaç ilke sağlamaktı.
türler ve yapılar ve kullanıcının bu ilkelleri birleştirmesine izin verir.
çok sayıda farklı yapı. Kullanıcı tanımlı veriler için bu hüküm
türler bir dereceye kadar tüm büyük zorunlu dillere taşındı
o zamandan beri tasarlandı. Kullanıcı tanımlı veri türleri, izin verdikleri için değerlidir.
kullanıcının belirli sorunlara çok yakından uyan veri soyutlamaları tasarlaması. Herşey
veri türlerinin yönleri Bölüm 6'da tartışılmaktadır.
Veri türleri alanında bir ilk olarak ALGOL 68,
Bölüm 5'te örtük yığın-dinamik olarak adlandırılacak olan dinamik diziler .
Dinamik dizi, bildirimin alt simge belirtmediği bir dizidir.
sınırlar. Dinamik bir diziye atamalar, gerekli depolamanın tahsisine neden olur.
ALGOL 68'de dinamik dizilere esnek diziler denir .
2.11.3 Değerlendirme
ALGOL 68, daha önce olmayan önemli sayıda özellik içerir.
özenle kullanılır. Bazılarının abartılı olduğunu iddia edebileceği ortogonallik kullanımı,
yine de devrimci.
Ancak ALGOL 68, ALGOL 60'ın günahlarından birini tekrarladı ve
sınırlı popülaritesinde önemli bir faktördür. Dil, bir
zarif ve özlü ama aynı zamanda bilinmeyen üst dil. Biri okuyamadan önce
dili tanımlayan belge (van Wijngaarden ve diğerleri, 1969), sahip olduğu
van Wijngaarden gramerleri adı verilen yeni üst dili öğrenmek için
BNF'den çok daha karmaşık. Daha da kötüsü, tasarımcılar icat etti
dilbilgisini ve dili açıklamak için bir kelime koleksiyonu. Örneğin,
anahtar kelimelere göstergeler, alt dizi çıkarma işlemine kırpma adı verildi ve
bir alt program yürütme süreci , prosedürden çıkarma zorlaması olarak adlandırıldı,
hangi olabilir ezik, firma, ya da başka bir şey.
PL/I'nin tasarımını ALGOL 68'in tasarımıyla karşılaştırmak doğaldır, çünkü
sadece birkaç yıl arayla ortaya çıktılar. ALGOL 68 tarafından yazılabilirlik elde edildi
diklik ilkesi: birkaç ilkel kavram ve sınırsız kullanım
birkaç birleştirme mekanizmasından oluşur. PL/I, büyük bir
Sabit yapıların sayısı. ALGOL 68, ürünün zarif sadeliğini genişletti.
ALGOL 60, oysa PL/I sadece birkaç lan-
hedeflerine ulaşacağını gösterir. Tabii unutulmamalıdır ki amaç
PL/I'nin amacı, geniş bir problem sınıfı için birleşik bir araç sağlamaktı.
ALGOL 68 tek bir sınıfa yönelikti: bilimsel uygulamalar.
PL/I, büyük ölçüde IBM'in
tanıtım çabaları ve anlama ve uygulama sorunları

Sayfa 96
ALGOL 68. Uygulama her ikisi için de zor bir problemdi, ancak PL/I
Bir derleyici oluşturmaya uygulanacak IBM kaynakları. ALGOL 68 zevk yok
böyle bir hayırsever.
2.12 ALGOL'lerin Bazı Erken Torunları
Tüm zorunlu diller, tasarımlarının bir kısmını ALGOL 60'a ve/veya
ALGOL 68. Bu bölüm, bu türlerin ilk torunlarından bazılarını tartışıyor.
Diller.
2.12.1 Tasarımda Sadelik: Pascal
2.12.1.1 Tarihsel Arka Plan
Niklaus Wirth (Wirth “Virt” olarak telaffuz edilir), Enternasyonal'in bir üyesiydi.
Bilgi İşlem Federasyonu (IFIP) Çalışma Grubu 2.1,
1960'ların ortalarında ALGOL'un gelişimini sürdürmek için yaratılmıştır. Ağustosda
1965, Wirth ve CAR (“Tony”) Hoare bu çabaya şu anda katkıda bulunarak-
gruba eklemeler ve değişiklikler için biraz mütevazı bir teklif
ALGOL 60'a (Wirth ve Hoare, 1966). Grubun çoğunluğu reddetti
ALGOL 60'a göre çok küçük bir gelişme olarak teklif.
daha karmaşık revizyon geliştirildi ve sonunda ALGOL 68 oldu.
Wirth, diğer birkaç grup üyesiyle birlikte, ALGOL'un
68 raporunun, her ikisinin de karmaşıklığına dayalı olarak yayımlanmış olması gerekirdi.
guage ve onu tanımlamak için kullanılan üst dil. Bu pozisyon daha sonra kanıtlandı
ALGOL 68 belgelerinin bir miktar geçerliliği olması ve dolayısıyla
dil, bilgisayar topluluğu tarafından gerçekten zorlayıcı bulundu.
ALGOL 60'ın Wirth ve Hoare versiyonuna ALGOL-W adı verildi. o
Stanford Üniversitesi'nde uygulandı ve öncelikli olarak bir öğretim aracı olarak kullanıldı.
ulusal araç, ancak sadece birkaç üniversitede. Birincil katkıları
ALGOL-W, parametreleri geçirmenin değer-sonuç yöntemiydi ve durum
çoklu seçim için ifade. Değer-sonuç yöntemi şuna bir alternatiftir:
ALGOL 60'ın isme göre geçiş yöntemi. Her ikisi de Bölüm 9'da tartışılmaktadır.
vaka bildirimi Bölüm 8'de tartışılmıştır.
Wirth'in yine ALGOL 60'a dayanan bir sonraki büyük tasarım çalışması,
başarılı: Pascal. 10 Pascal'ın orijinal yayınlanmış tanımı,
1971 (Wirth, 1971). Bu sürüm uygulamada biraz değiştirildi.
işlemidir ve Wirth (1973)'te açıklanmıştır. Genellikle olan özellikler
Pascal'a atfedilen kelimeler aslında daha önceki dillerden gelmektedir. Örneğin, kullanıcı-
tanımlı veri türleri ALGOL 68, tanıtıldı vaka açıklamada
ALGOL-W ve Pascal'ın kayıtları COBOL ve PL/I'ninkilere benzer.
10. Pascal, adını on yedinci yüzyıl Fransız filozofu ve matematikçisi Blaise Pascal'dan almıştır.
1642'de (diğer şeylerin yanı sıra) ilk mekanik ekleme makinesini icat eden tician.
2.12 ALGOL'lerin Bazı Erken Torunları 75

Sayfa 97
76
Bölüm 2 Başlıca Programlama Dillerinin Evrimi
2.12.1.2 Değerlendirme
Pascal'ın en büyük etkisi programlama öğretimi üzerinde olmuştur. 1970 yılında
bilgisayar bilimi, mühendislik ve bilim öğrencilerinin çoğu tanıtıldı
Bazı üniversiteler PL/I, diller kullansa da, Fortran ile programlamaya
PL/I ve ALGOL-W'ye dayalıdır. 1970'lerin ortalarında Pascal,
Bu amaçla en yaygın olarak kullanılan dildir. Bu oldukça doğaldı, çünkü
Pascal, özellikle programlama öğretmek için tasarlanmıştır. kadar değildi
1990'ların sonlarında Pascal'ın artık en yaygın kullanılan dil olmadığı
kolejlerde ve üniversitelerde programlama öğretimi.
Pascal bir öğretim dili olarak tasarlandığından, çeşitli özelliklerden yoksundur.
birçok uygulama türü için gereklidir. Bunun en güzel örneği
parametre olarak bir dizi alan bir alt program yazmanın imkansızlığı
değişken uzunlukta. Başka bir örnek, herhangi bir ayrı derlemenin olmamasıdır.
kabiliyet. Bu eksiklikler doğal olarak birçok standart olmayan lehçeye yol açtı.
Turbo Pascal olarak.
Pascal'ın hem programlama öğretiminde hem de diğer uygulamalardaki popülaritesi,
temel olarak sadelik ve ifadenin olağanüstü kombinasyonuna dayanıyordu.
sivi. Pascal'da bazı güvensizlikler olsa da, yine de nispeten güvenlidir.
dil, özellikle Fortran veya C ile karşılaştırıldığında. 1990'ların ortalarında,
Pascal'ın popülaritesi hem endüstride hem de üniversitede düşüşteydi.
Öncelikle Modula-2, Ada ve C++'ın yükselişi nedeniyle bağlar
Pascal'da mevcut olmayan özellikler.
Aşağıda bir Pascal programı örneği verilmiştir:
{Pascal Örnek Programı
Girdi: listlen'in şundan küçük olduğu bir tamsayı, listlen
100, ardından listlen-integer değerleri
Çıktı: Daha büyük olan girdi değerlerinin sayısı
tüm girdi değerlerinin ortalaması }
program pasex (giriş, çıkış);
tip intlisttype = dizi [1..99] arasında bir tamsayı;
var
intlist : intlisttype;
listlen, sayaç, toplam, ortalama, sonuç : tamsayı;
başlamak
sonuç := 0;
toplam := 0;
readln (dinle);
if ((listlen > 0) ve (listlen < 100)) o zaman
başlamak
{ Girdiyi bir diziye okuyun ve toplamı hesaplayın }
için sayaç: 1 = hiç listlen yapmak
başlamak
readln (intlist[sayaç]);
toplam := toplam + iç liste[sayaç]
son;

Sayfa 98
{ Ortalamayı hesaplayın }
ortalama := toplam / listelen;
{ > ortalama olan giriş değerlerinin sayısını sayın }
için sayaç: 1 = hiç listlen yapmak
if (intlist[sayaç] > ortalama) o zaman
sonuç := sonuç + 1;
{ Sonucu yazdırın }
writeln ('Değer sayısı > ortalama:',
sonuç)
sonu {ardından maddesinin if ((listlen> 0 ...}
Başka
writeln ('Hata—giriş listesi uzunluğu yasal değil')
son.
2.12.2 Taşınabilir Sistemler Dili: C
Pascal gibi, C de önceden bilinen dil koleksiyonuna çok az katkıda bulunmuştur.
özellikleri, ancak uzun bir süre boyunca yaygın olarak kullanılmaktadır. Her ne kadar köken-
Son olarak sistem programlaması için tasarlanmış olan C, çok çeşitli
uygulamalar.
2.12.2.1 Tarihsel Arka Plan
C'nin ataları CPL, BCPL, B ve ALGOL 68'i içerir.
1960'ların başında Cambridge Üniversitesi. BCPL basit bir sistem dilidir,
Ayrıca Cambridge'de, bu sefer Martin Richards tarafından 1967'de geliştirildi (Richards,
1969).
UNIX işletim sistemi üzerinde ilk çalışma 1960'ların sonlarında
Ken Thompson, Bell Laboratuvarlarında. İlk versiyon montajda yazılmıştır
dilim. UNIX altında uygulanan ilk yüksek seviyeli dil B idi.
BCPL'ye dayanıyordu. B, 1970 yılında Thompson tarafından tasarlanmış ve uygulanmıştır.
Ne BCPL ne de B, yazılan bir dil değildir, bu da aralarında bir tuhaflıktır.
yüksek seviyeli diller, ancak her ikisi de bir dilden çok daha düşük seviyeli
Java gibi. Türlenmemiş olmak, tüm verilerin makine olarak kabul edildiği anlamına gelir
basit olmasına rağmen birçok komplikasyona ve güvensizliğe yol açan kelimeler
bağlar. Örneğin, bunun yerine kayan nokta belirtme sorunu var.
bir ifadede tamsayı aritmetiğinden daha fazla. BCPL'nin bir uygulamasında,
kayan nokta işleminin değişken işlenenlerinden önce peri-
ods. Başında periyot olmayan değişken işlenenler, etkileşimli olarak kabul edildi.
gerler. Buna bir alternatif, farklı semboller kullanmak olabilir.
kayan nokta operatörleri.
Bu problem, diğer birçok problemle birlikte, bir
B'ye dayalı yeni yazılan dil. Başlangıçta NB olarak adlandırılır, ancak daha sonra C olarak adlandırılır,
Dennis Ritchie tarafından Bell Laboratuvarlarında tasarlanmış ve uygulanmıştır.
1972 (Kernighan ve Ritchie, 1978). Bazı durumlarda BCPL aracılığıyla ve
diğer durumlarda doğrudan, C, ALGOL 68'den etkilenmiştir .
2.12 ALGOL'lerin Bazı Erken Torunları 77

Sayfa 99
78
Bölüm 2 Başlıca Programlama Dillerinin Evrimi
ve anahtar ifadeleri, atama operatörlerinde ve işlenmesinde
işaretçiler.
C için ilk bir buçuk yılda tek "standart", yazarın kitabıydı.
Kernighan ve Ritchie (1978). 11 Bu zaman diliminde, dil yavaş yavaş
farklı uygulayıcılar farklı özellikler ekleyerek gelişti. 1989 yılında ANSI
C'nin resmi bir tanımını üretti (ANSI, 1989), ve bunların birçoğunu içeriyordu.
uygulayıcıların zaten dile dahil ettiği özellikler.
Bu standart 1999 yılında güncellenmiştir (ISO, 1999). Bu sonraki sürüm, bir
dilde birkaç önemli değişiklik. Bunlar arasında karmaşık bir veri türü,
Boolean veri türü ve C++ stili yorumlar ( // ). 1989'a değineceğiz.
uzun süredir ANSI C olarak adlandırılan sürüm, C89 olarak; 1999'a değineceğiz
C99 olarak sürüm.
2.12.2.2 Değerlendirme
C yeterli kontrol ifadelerine ve veri yapılandırma olanaklarına sahiptir.
birçok uygulama alanında kullanın. sağlayan zengin bir operatör grubuna sahiptir.
yüksek derecede ifade gücü.
C'nin hem sevilmesi hem de sevilmemesinin en önemli nedenlerinden biri,
tam tip kontrolünün olmaması. Örneğin, C99'dan önceki sürümlerde, işlevler
hangi parametrelerin tip kontrolü yapılmadığı yazılabilir. beğenenler
C esnekliği takdir eder; sevmeyenler çok güvensiz buluyor. Büyük bir
1980'lerde popülaritesindeki büyük artışın nedeni, onun için bir derleyici olmasıydı.
yaygın olarak kullanılan UNIX işletim sisteminin bir parçasıydı. UNIX'e bu dahil etme
pro-
birçok farklı bilgisayar türünde gramer.
Aşağıda bir C programı örneği verilmiştir:
/* C Örnek Programı
Girdi: listlen'in şundan küçük olduğu bir tamsayı, listlen
100, ardından listlen-integer değerleri
Çıktı: Daha büyük olan girdi değerlerinin sayısı
tüm giriş değerlerinin ortalaması */
int ana (){
int intlist[99], listlen, sayaç, toplam, ortalama, sonuç;
toplam = 0;
sonuç = 0;
scanf("%d", &listlen);
if ((listlen > 0) && (listlen < 100)) {
/* Girdiyi bir diziye oku ve toplamını hesapla */
for (sayaç = 0; sayaç < listlen; sayaç++) {
scanf("%d", &intlist[sayaç]);
toplam += intlist[sayaç];
}
11. Bu dile genellikle “K & R C” denir.

Sayfa 100
/* Ortalamayı hesapla */
ortalama = toplam / dinle;
/* > ortalama olan giriş değerlerini sayın */
for (sayaç = 0; sayaç < listlen; sayaç++)
if (intlist[sayaç] > ortalama) sonuç++;
/* Sonucu yazdır */
printf("Değer sayısı > ortalama:%d\n", sonuç);
}
Başka
printf("Hata—giriş listesi uzunluğu yasal değil\n");
}
2.13 Mantığa Dayalı Programlama: Prolog
Basitçe söylemek gerekirse, mantıksal programlama, iletişim kurmak için resmi bir mantık gösteriminin kullanılmasıdır.
Bilgisayara uygun hesaplama süreçleri. Yüklem hesabı gösterimdir
Mevcut mantık programlama dillerinde kullanılır.
Mantıksal programlama dillerinde programlama prosedürel değildir. pro-
bu tür dillerdeki gramlar, bir sonucun tam olarak nasıl hesaplanacağını belirtmez, ancak
bunun yerine sonucun gerekli biçimini ve/veya özelliklerini tanımlayın. Nedir
Mantıksal programlama dillerinde bu yeteneği sağlamak için gerekli olan kısa ve öz
bilgisayara hem ilgili bilgileri hem de bir
İstenen sonuçları hesaplamak için çıkarım süreci. Yüklem hesabı malzemeleri
Bilgisayarla iletişimin temel biçimi ve ispat yöntemi,
İlk olarak Robinson (1965) tarafından geliştirilen adlandırılmış çözünürlük, çıkarsama sağlar.
tekniği.
2.13.1 Tasarım Süreci
1970'lerin başında, Alain Colmerauer ve Phillippe Roussel, Arti-
Robert ile birlikte Aix-Marseille Üniversitesi'nde Sosyal İstihbarat Grubu
Edin Üniversitesi Yapay Zeka Bölümü'nden Kowalski,
Burgh, Prolog'un temel tasarımını geliştirdi. Birincil bileşenler
of Prolog, yüklem hesabı önermelerini belirtmek için bir yöntemdir ve
sınırlı bir çözüm biçiminin uygulanması. Hem yüklem hesabı hem de
çözünürlük Bölüm 16'da açıklanmıştır. İlk Prolog yorumlayıcısı geliştirildi.
1972'de Marsilya'da açıldı. Uygulanan dilin versiyonu
Roussel'de (1975) anlatılmıştır. Adı Prolog dan yanlısı gramming günlüğü ic.
2.13.2 Dile Genel Bakış
Prolog programları, ifade koleksiyonlarından oluşur. Prolog'da sadece birkaç tane var
tür ifadeler, ancak karmaşık olabilirler.
2.13 Mantığa Dayalı Programlama: Prolog 79

Sayfa 101
80
Bölüm 2 Başlıca Programlama Dillerinin Evrimi
Prolog'un yaygın bir kullanımı, bir tür akıllı veritabanıdır. Bu uygulama-
cation, Prolog dilini tartışmak için basit bir çerçeve sağlar.
Bir Prolog programının veri tabanı iki tür ifadeden oluşur: gerçekler
ve kurallar. Aşağıdakiler olgu bildirimlerinin örnekleridir:
anne(joanne, jake).
baba(vern, joanne).
O Bu durum Joanne olan anne ve Jake ve vern olan baba arasında
joanne .
Bir kural ifadesi örneği,
grandparent(X, Z) :- parent(X, Y), parent(Y, Z).
O olduğu sonucuna varılabilir ki bu devletler X'in olan büyükbaba ve Z eğer doğruysa
bu X, bir üst ve Y ve Y, üstüdür Z için bazı özel değerler için,
X , Y ve Z değişkenleri .
Prolog veritabanı, hedef ifadeleri ile etkileşimli olarak sorgulanabilir,
bunun örneği
baba(bob, darcie).
Bu sorar bob olan baba arasında Darcie . Böyle bir sorgu veya hedef olduğunda
Prolog sistemine sunulduğunda, çözüm sürecini denemek için kullanır.
ifadenin doğruluğunu belirler. Amacın doğru olduğu sonucuna varabilirse,
"doğru" gösterir. Kanıtlayamazsa, “yanlış” gösterir.
2.13.3 Değerlendirme
1980'lerde, nispeten küçük bir bilgisayar bilimci grubu vardı.
mantık programlamanın, bu sorunlardan kaçmak için en iyi umudu sağladığına inanıyordu.
zorunlu dillerin karmaşıklığı ve ayrıca muazzam problem-
ihtiyaç duyulan büyük miktarda güvenilir yazılım üretmeyi sağlar.
Ancak şimdiye kadar, mantıksal programlamanın iki ana nedeni vardır.
daha yaygın olarak kullanılmaz. İlk olarak, diğer bazı zorunlu olmayanlarda olduğu gibi
yaklaşımlar, mantık dillerinde yazılmış programlar şimdiye kadar kanıtladı
eşdeğer zorunlu programlara göre oldukça verimsiz olmak. İkincisi, o
göreli olarak sadece birkaçı için etkili bir yaklaşım olduğu belirlenmiştir.
küçük uygulama alanları: belirli veri tabanı yönetim sistemleri ve
AI'nın bazı alanları.
Nesne yönelimli programlamayı destekleyen bir Prolog lehçesi vardır—
Prolog++ (Moss, 1994). Mantıksal programlama ve Prolog,
Bölüm 16'da daha fazla ayrıntı.

Sayfa 102
2.14 Tarihin En Büyük Tasarım Çabası: Ada
Ada dili, en kapsamlı ve pahalı dilin sonucudur.
tasarım çabası şimdiye kadar üstlenildi. Aşağıdaki paragraflar kısaca şunları açıklamaktadır:
Ada'nın evrimi.
2.14.1 Tarihsel Arkaplan
Ada dili, Savunma Bakanlığı (DoD) için geliştirildi, bu nedenle
bilgisayar ortamının durumu, biçimini belirlemede etkili oldu.
1974'te Savunma Bakanlığı'ndaki bilgisayar uygulamalarının yarısından fazlası gömülü sistemlerdi.
Tem. Gömülü sistem, bilgisayar donanımının gömülü olduğu sistemdir.
kontrol ettiği veya hizmet sunduğu cihaz. Yazılım maliyetleri artıyor
öncelikle sistemlerin artan karmaşıklığı nedeniyle hızlı bir şekilde. 450'den fazla
Savunma Bakanlığı projeleri için farklı programlama dilleri kullanılıyordu ve bunların hiçbiri
DoD tarafından standardize edilmiştir. Her savunma müteahhidi yeni ve farklı bir
her sözleşme için ent dili. 12 Bu dilin yaygınlaşması nedeniyle uygulama-
tion yazılımı nadiren yeniden kullanıldı. Ayrıca, hiçbir yazılım geliştirme aracı
oluşturulur (çünkü genellikle dile bağımlıdırlar). Çok sayıda dil
kullanımdaydı, ancak hiçbiri gömülü sistem uygulamaları için gerçekten uygun değildi.
Bu nedenlerle, 1974'te Kara, Deniz ve Hava Kuvvetlerinin her biri bağımsız olarak
gömülü sistemler için tek bir yüksek seviyeli dilin geliştirilmesini önerdi.
2.14.2 Tasarım Süreci
Bu yaygın ilgiye dikkat çekerek, Ocak 1975'te, Malcolm Currie,
Savunma Araştırma ve Mühendisliği, Yüksek Dereceli Dil Çalışmasını kurdu.
Grup (HOLWG), başlangıçta Lt. Albay William Whitaker tarafından yönetildi.
Hava Kuvvetleri. HOLWG'nin tüm askeri hizmetlerden temsilcileri vardı
ve Büyük Britanya, Fransa ve o zamanlar Batı Almanya olan ülkelerle ilişkiler. Onun
ilk tüzük aşağıdakileri yapmaktı:
• Yeni bir Savunma Bakanlığı üst düzey dili için gereksinimleri belirleyin.
• Uygulanabilir bir dil olup olmadığını belirlemek için mevcut dilleri değerlendirin
aday.
• Minimal bir programlama setinin benimsenmesini veya uygulanmasını önermek
Diller.
Nisan 1975'te HOLWG, Strawman gereksinimleri belgesini üretti.
yeni dil için ment (Savunma Bakanlığı, 1975a). Bu dağıtım-
askeri şubeler, federal kurumlar, seçilmiş sanayi ve üniversite
Avrupa'daki temsilciler ve ilgili taraflar.
12. Bu sonuç, büyük ölçüde, gömülü sistemler için montaj dilinin yaygın kullanımından kaynaklanmaktadır.
Çoğu gömülü sistemin özel işlemciler kullanması gerçeğiyle birlikte.
2.14 Tarihin En Büyük Tasarım Çabası: Ada 81

Sayfa 103
82
Bölüm 2 Başlıca Programlama Dillerinin Evrimi
Strawman belgesini Woodenman (Departmanı) izlemiştir.
Savunma, 1975b) Ağustos 1975'te, Tinman (Savunma Bakanlığı, 1976)
Ocak 1976, Ironman (Savunma Bakanlığı, 1977) Ocak 1977'de ve
nihayet Haziran 1978'de Steelman (Savunma Bakanlığı, 1978).
Sıkıcı bir süreçten sonra, dil için sunulan birçok teklif
hepsi Pascal'a dayanan dört finaliste indirildi. İçinde
Mayıs 1979, Cii Honeywell/Bull dil tasarım önerisi aşağıdakilerden seçilmiştir.
kullanılacak tasarım olarak dört finalist. Cii Honeywell/Boğa
Son dördün içindeki tek yabancı yarışmacı olan Fransa'daki tasarım ekibi,
Jean Ichbiah tarafından yönetilmektedir.
1979 baharında, Donanma Malzeme Komutanlığı'ndan Jack Cooper,
Ada, daha sonra kabul edilen yeni dilin adını övdü. bu
adı Augusta Ada Byron'ı (1815-1851), Lovelace kontesini anıyor,
matematikçi ve şair Lord Byron'ın kızı. O genellikle tanınır
dünyanın ilk programcısı olarak. Charles Babbage ile çalıştı.
mekanik bilgisayarları, Fark ve Analitik Motorlar, pro-
birkaç sayısal işlem için gram.
Ada'nın tasarımı ve gerekçesi ACM tarafından yayımlandı.
SIGPLAN Notices (ACM, 1979) ve birden fazla okuyucuya dağıtıldı.
10.000 kişi. Ekim ayında halka açık bir test ve değerlendirme konferansı düzenlendi
1979, Boston'da 100'den fazla kuruluşun temsilcileriyle
Amerika Birleşik Devletleri ve Avrupa. Kasım ayına kadar 500'den fazla dil raporu
15 farklı ülkeden alındı. Önerilen raporların çoğu
sert değişiklikler ve doğrudan reddetmeler yerine küçük değişiklikler. Temelli
dil raporlarında, gereksinim belirtiminin bir sonraki sürümü,
Stoneman belgesi (Savunma Bakanlığı, 1980a), ABD'de yayınlandı.
Şubat 1980.
Dil tasarımının gözden geçirilmiş bir versiyonu Temmuz 1980'de tamamlandı ve
standart Ada Dili Referans Kılavuzu olan MIL-STD 1815 olarak kabul edildi .
1815 sayısı, Augusta'nın doğum yılı olduğu için seçilmiştir.
Ada Byron. Ada Dili Referans Kılavuzunun gözden geçirilmiş başka bir versiyonu
Temmuz 1982'de piyasaya sürüldü. 1983'te Amerikan Ulusal Standartlar Enstitüsü
tute standardize Ada. Bu "nihai" resmi sürüm Goos ve
Hartmanis (1983). Ada dili tasarımı daha sonra minimum düzeyde donduruldu
beş yıllık.
2.14.3 Dile Genel Bakış
Bu alt bölüm, Ada'nın başlıca katkılarından dördünü kısaca açıklamaktadır.
dilim.
Ada dilindeki paketler, verileri kapsüllemek için araçlar sağlar
nesneler, veri türleri için özellikler ve prosedürler. Bu, sırayla, sağlar
bölümünde açıklandığı gibi, program tasarımında veri soyutlamasının kullanımına yönelik destek
Bölüm 11.
Ada dili, istisna işleme için kapsamlı olanaklar içerir,
Bu, programcının çok çeşitli seçeneklerden herhangi birinden sonra kontrolü ele geçirmesine izin verir.

Sayfa 104
özel durumlar veya çalışma zamanı hataları algılandı. İstisna işleme
Bölüm 14'te tartışılmıştır.
Program birimleri Ada'da genel olabilir. Örneğin, yazmak mümkün
sıralanacak veriler için belirtilmemiş bir tür kullanan bir sıralama prosedürü.
Böyle bir genel prosedür, önceden belirlenmiş bir tür için somutlaştırılmalıdır.
derleyicinin çalışmasına neden olan bir ifadeyle yapılan kullanılabilir.
verilen tipte prosedürün bir versiyonunu oluşturun. Uygunluk
Bu tür genel birimlerin sayısı, olabilecek program birimlerinin aralığını artırır.
programcılar tarafından çoğaltılmak yerine yeniden kullanılır. Jenerikler tartışılır
9. ve 11. bölümler.
Ada dili ayrıca özel pro-
randevu mekanizmasını kullanarak, adlandırılmış görevler, gram birimleri. Randevu
görevler arası iletişim ve senkronizasyon yönteminin adı. Hemfikir olmak-
rency, Bölüm 13'te tartışılmaktadır.
2.14.4 Değerlendirme
Ada dilinin tasarımının belki de en önemli yönleri,
yanlar şunlardır:
• Tasarım rekabetçi olduğu için katılımda sınır yoktu.
• Ada dili, yazılım mühendisliği kavramlarının çoğunu bünyesinde barındırır.
1970'lerin sonlarında dil tasarımı. Her ne kadar sorgulanabilse de
bilgeliğin yanı sıra bu özellikleri birleştirmek için kullanılan gerçek yaklaşımlar
bir dilde bu kadar çok sayıda özelliğin dahil edilmesi konusunda çoğu kişi şu konuda hemfikirdir.
özellikler değerlidir.
• Çoğu insan bunu tahmin etmese de, bir derleyicinin gelişimi
Ada dili için zor bir işti. Sadece 1985'te, neredeyse dört yıl
dil tasarımı tamamlandıktan sonra gerçekten kullanılabilir Ada derleyicileri yaptı
görünmeye başlar.
Ada'nın ilk birkaç yılındaki en ciddi eleştirisi, çok
büyük ve çok karmaşık. Özellikle, Hoare (1981) yapılmaması gerektiğini belirtmiştir.
güvenilirliğin kritik olduğu herhangi bir uygulama için kullanılır, ki bu tam olarak türdür
tasarlanmış olduğu uygulama. Öte yandan, diğerleri övdü
kendi dönemi için dil tasarımının özü olarak. Aslında, Hoare bile sonunda
dile bakışını yumuşattı.
Aşağıda bir Ada programı örneği verilmiştir:
-- Ada Örnek Programı
-- Girdi: List_Len'in daha az olduğu bir tamsayı, List_Len
--
100'den fazla, ardından List_Len-tamsayı değerleri
-- Çıktı: Daha büyük olan girdi değerlerinin sayısı
--
tüm girdi değerlerinin ortalamasından
ile Ada.Text_IO, Ada.Integer.Text_IO;
Ada.Text_IO, Ada.Integer.Text_IO kullanın ;
2.14 Tarihin En Büyük Tasarım Çabası: Ada 83

Sayfa 105
84
Bölüm 2 Başlıca Programlama Dillerinin Evrimi
prosedür Ada_Ex olduğu
tip Int_List_Type dizisidir (1..99) arasında bir tamsayı;
Int_List : Int_List_Type;
List_Len, Toplam, Ortalama, Sonuç : Tamsayı;
başlamak
Sonuç:= 0;
Toplam := 0;
Al (List_Len);
Eğer (List_Len> 0) ve (List_Len <100) daha sonra
-- Girdi verilerini bir diziye okuyun ve toplamı hesaplayın
için Sayaç: = 1 .. List_Len döngü
Get (Int_List(Sayaç));
Toplam := Toplam + Int_List(Sayaç);
son döngü;
-- Ortalamayı hesaplayın
Ortalama := Toplam / List_Len;
-- > ortalama olan değerlerin sayısını sayın
için Sayaç: = 1 .. List_Len döngü
eğer Int_List (Sayaç)> Ortalama ardından
Sonuç:= Sonuç+ 1;
eğer son;
son döngü;
-- Baskı sonucu
Put ("Değerlerin sayısı > ortalama:");
Koy (Sonuç);
Yeni hat;
Başka
Put_Line ("Hata—giriş listesi uzunluğu yasal değil");
eğer son;
son Ada_Ex;
2.14.5 Ada 95 ve Ada 2005
Ada 95'in en önemli yeni özelliklerinden ikisi, aşağıda kısaca açıklanmıştır.
aşağıdaki paragraflar. Kitabın geri kalanında Ada adını kullanacağız.
Orijinal sürüm için 83 ve sonraki sürüm için Ada 95 (gerçek adı)
iki sürüm arasında ayrım yapmak önemli olduğunda. tartışmalarında
Her iki sürümde de ortak olan dil özellikleri için Ada adını kullanacağız. bu
Ada 95 standart dili ARM'de (1995) tanımlanmıştır.
Ada 83'ün tip türetme mekanizması Ada 95'te genişletilmiştir.
bir temel sınıftan miras alınanlara yeni bileşenler ekleme. Bu sağlar
kalıtım için, nesne yönelimli programlama dillerinde önemli bir bileşen.
Alt program çağrılarının alt program tanımlarına dinamik olarak bağlanması,
etiket değerine dayanan alt program gönderimi yoluyla
sınıf çapında türler aracılığıyla türetilmiş türler. Bu özellik polimorfizm sağlar,

Sayfa 106
nesne yönelimli programlamanın bir başka temel özelliği. Bu özellikler
Ada 95, Bölüm 12'de tartışılmaktadır.
Ada 83'ün randevu mekanizması yalnızca hantal ve
eşzamanlı süreçler arasında veri paylaşımının verimsiz araçları. öyle gerekti
paylaşılan verilere erişimi kontrol etmek için yeni bir görev tanıtmak. korunan
Ada 95'in nesneleri buna çekici bir alternatif sunuyor. Paylaşılan veriler
ya da verilere tüm erişimi kontrol eden bir sözdizimsel yapı içinde kapsüllenmiştir.
randevu ile veya alt program çağrısı ile. Uyum için Ada 95'in yeni özellikleri
rency ve paylaşılan veriler Bölüm 13'te tartışılmaktadır.
Ada 95'in popülaritesinin zarar gördüğüne inanılıyor çünkü
Savunma Bakanlığı, askeri yazılımda kullanılmasını gerektirmeyi bıraktı
sistemler. Büyümesini engelleyen başka faktörler de vardı elbette.
popülerlik. Bunlardan en önemlisi, yaygın olarak kabul edilmesiydi.
Ada 95'ten önce ortaya çıkan nesne yönelimli programlama için C++
piyasaya sürülmüş.
Ada 2005'i almak için Ada 95'e birkaç ekleme yapıldı.
Java'ya benzer arayüzler, zamanlama algoritmaları üzerinde daha fazla kontrol ve
senkronize arayüzler
Ada, hem ticari hem de savunma amaçlı aviyonik, hava trafiğinde yaygın olarak kullanılmaktadır.
kontrol ve demiryolu taşımacılığının yanı sıra diğer alanlarda.
2.15 Nesne Yönelimli Programlama: Smalltalk
Smalltalk, nesneyi tam olarak destekleyen ilk programlama diliydi.
odaklı programlama Bu nedenle, herhangi bir tartışmanın önemli bir parçasıdır.
programlama dillerinin evrimi.
2.15.1 Tasarım Süreci
Smalltalk'ın gelişmesine yol açan kavramlar, Ph.D.
Alan Kay'ın 1960'ların sonlarında Utah Üniversitesi'ndeki doktora tez çalışması (Kay,
1969). Kay, gelecekteki kullanılabilirliğini tahmin etmek için olağanüstü bir öngörüye sahipti.
güçlü masaüstü bilgisayarlar. Hatırlayın, ilk mikrobilgisayar sistemleri
1970'lerin ortalarına kadar pazarlanmadı ve yalnızca uzaktan ilişkiliydiler.
bir milyonu çalıştırdığı görülen Kay tarafından tasarlanan makinelere
saniyede daha fazla talimat ve birkaç megabayt bellek içerir. Çok
iş istasyonları biçimindeki makineler, yalnızca
1980'lerin başı.
Kay, masaüstü bilgisayarların programcı olmayanlar tarafından kullanılacağına inanıyordu.
ve bu nedenle çok güçlü insan arabirimi yeteneklerine ihtiyaç duyacaktır. Com-
1960'ların sonundaki bilgisayarlar büyük ölçüde parti odaklıydı ve yalnızca
profesyonel programcılar ve bilim adamları tarafından. Programcı olmayanlar tarafından kullanım için, Kay
belirlendiğinde, bir bilgisayarın yüksek düzeyde etkileşimli olması ve karmaşık
kullanıcı arayüzünde yer alan grafikler. Bazı grafik konseptleri
2.15 Nesneye Yönelik Programlama: Smalltalk 85

Sayfa 107
86
Bölüm 2 Başlıca Programlama Dillerinin Evrimi
yardımcı olmak için grafiklerin kullanıldığı Seymour Papert'in LOGO deneyimi
çocukların bilgisayar kullanımında (Papert, 1980).
Kay, başlangıçta Dynabook adını verdiği bir sistemi tasavvur etmişti.
genel bir bilgi işlemcisi olmak. Kısmen Flex diline dayanıyordu,
tasarımına yardım etmişti. Flex, öncelikle SIMULA 67'ye dayanıyordu. Dynabook
üzerinde birkaç kağıt bulunan tipik masa paradigmasını kullandı,
bazıları kısmen örtülüdür. Üst sayfa genellikle dikkatin odak noktasıdır, diğer
ers geçici olarak odak dışında. Dynabook'un ekranı bu sahneyi modelleyecektir,
masaüstünde çeşitli kağıt yapraklarını temsil etmek için ekran pencerelerini kullanma. bu
kullanıcı böyle bir ekranla hem tuş vuruşlarıyla hem de dokunarak etkileşime girecektir.
parmaklarıyla ekrana bakıyor. Dynabook'un ön tasarımından sonra
ona bir doktora kazandıktan sonra, Kay'in amacı böyle bir makinenin yapıldığını görmek oldu.
Kay, Xerox Palo Alto Araştırma Merkezi'ne (Xerox PARC) giden yolunu buldu
ve fikirlerini Dynabook'ta sundu. Bu onun orada çalışmasına ve
Xerox'ta Öğrenme Araştırma Grubu'nun sonraki doğumu. İlk suçlama
grup, Kay'in programlama paradigmasını desteklemek için bir dil tasarlamaktı.
ve o zaman mevcut olan en iyi kişisel bilgisayarda uygulayın. Bu çabalar
Xerox Alto iş istasyonundan oluşan bir "Geçici" Dynabook ile sonuçlandı
ve Smalltalk-72 yazılımı. Birlikte, daha fazlası için bir araştırma aracı oluşturdular.
gelişim. Bu sistemle bir dizi araştırma projesi yürütüldü,
çocuklara programlamayı öğretmek için çeşitli deneyler dahil. İle birlikte
deneyler, bir dizi dilin ortaya çıkmasına yol açan daha fazla gelişme getirdi.
Smalltalk-80 ile sona erdi. Dil büyüdükçe, dilin gücü de arttı.
üzerinde bulunduğu donanım. 1980'e gelindiğinde, hem dil hem de Xerox sert-
ware Alan Kay'in ilk vizyonuyla neredeyse eşleşti.
2.15.2 Dile Genel Bakış
Smalltalk dünyası, tamsayı birleşiminden yalnızca nesnelerle doldurulur.
büyük karmaşık yazılım sistemlerine karşılık gelir. Smalltalk'taki tüm hesaplamalar tamamlandı
aynı tek tip teknikle: birini çağırmak için bir nesneye mesaj göndermek
yöntemlerinden biridir. Bir mesaja verilen yanıt,
talep edilen bilgi veya sadece göndericiye talep edilen işlemin bildirilmesi-
ing tamamlandı. Bir mesaj ve bir mesaj arasındaki temel fark
alt program çağrısı şudur: Bir veri nesnesine, özellikle bunlardan birine bir mesaj gönderilir.
nesne için tanımlanan yöntemler. Çağrılan yöntem daha sonra yürütülür, genellikle
mesajın gönderildiği nesnenin verilerini değiştirmek; bir alt program
çağrı, bir alt programın koduna bir mesajdır. Genellikle işlenecek veriler
alt program tarafından kendisine parametre olarak gönderilir. 13
Smalltalk'ta nesne soyutlamaları, sınıflara çok benzeyen sınıflardır.
SIMULA 67 sınıfları. Sınıfın örnekleri oluşturulabilir ve daha sonra
programın nesneleri.
Smalltalk'ın sözdizimi, diğer programlama dillerinin çoğundan farklıdır.
Guage, büyük ölçüde aritmetikten ziyade mesajların kullanımından ve
13. Elbette, bir yöntem çağrısı, çağrılan yöntem tarafından işlenecek verileri de iletebilir.

Sayfa 108
mantıksal ifadeler ve geleneksel kontrol ifadeleri. Smalltalk'tan biri
kontrol yapıları bir sonraki alt bölümdeki örnekte gösterilmektedir.
2.15.3 Değerlendirme
Smalltalk, bilgisayarın iki ayrı yönünü desteklemek için çok şey yaptı.
ing: grafiksel kullanıcı arayüzleri ve nesne yönelimli programlama. Pencere-
artık yazılıma kullanıcı arabirimlerinin baskın yöntemi olan sistemler
sistemler Smalltalk'tan doğdu. Günümüzün en önemli yazılım tasarımı
metodolojiler ve programlama dilleri nesne yönelimlidir. rağmen
Nesne yönelimli dillerin bazı fikirlerinin kökeni SIMULA'dan geldi.
67, Smalltalk'ta olgunlaşmaya ulaştılar. Smalltalk'ın etkisi açıktır.
bilgi işlem dünyası geniş ve uzun ömürlü olacak.
Aşağıda Smalltalk sınıf tanımına bir örnek verilmiştir:
"Smalltalk Örnek Programı"
"Aşağıdaki bir sınıf tanımıdır, örnekler
herhangi bir sayıda eşkenar çokgen çizebilen
taraf"
sınıf adı
Çokgen
üst sınıf
Nesne
örnek değişken adları
bizimKalem
numSides
kenar uzunluğu
"Sınıf yöntemleri"
"Bir örnek oluştur"
yeni
^ süper yeni getPen
"Çokgen çizmek için bir kalem alın"
getPen
ourPen <- Kalem yeni varsayılanUç : 2
"Örnek yöntemleri"
"Bir çokgen çizin"
Berabere
numSides timesRepeat: [ourPen go: sideLength;
dönüş: 360 // numSides]
"Kenarların uzunluğunu ayarla"
uzunluk: uzun
yanUzunluk <- len
"Taraf sayısını ayarla"
taraf: num
numSides <- num
2.15 Nesne Yönelimli Programlama: Smalltalk 87

Sayfa 109
88
Bölüm 2 Başlıca Programlama Dillerinin Evrimi
2.16 Zorunlu ve Nesne Yönelimli Özellikleri Birleştirme: C++
C'nin kökenleri Bölüm 2.12'de tartışıldı; Simula 67'nin kökenleri
Bölüm 2.10'da tartışılmıştır; Smalltalk'ın kökenleri Bölüm'de tartışıldı
2.15. C++, Simula 67'den ödünç alınan dil olanaklarını C'nin üzerine kurar.
Smalltalk'ın öncülük ettiği şeylerin çoğunu destekler. C++, C'den başlayarak
zorunlu özelliklerini geliştirmek ve ek özellikler eklemek için bir dizi değişiklik
Nesne yönelimli programlamayı destekleyen yapılar.
2.16.1 Tasarım Süreci
C'den C++'a doğru ilk adım Bell'de Bjarne Stroustrup tarafından atıldı.
1980'deki Laboratuarlar. C'deki ilk değişiklikler, eklemeyi içeriyordu.
fonksiyon parametre tipi kontrolü ve dönüşümü ve daha da önemlisi,
SIMULA 67 ve Smalltalk ile ilgili sınıflar. Ayrıca dahil
türetilmiş sınıflar, miras alınan bileşenlerin genel/özel erişim kontrolü,
yapıcı ve yıkıcı yöntemler ve arkadaş sınıfları. 1981 yılı boyunca, satır içi
işlevler, varsayılan parametreler ve atama operatörünün aşırı yüklenmesi
katma. Ortaya çıkan dile Sınıflar ile C adı verildi ve şurada açıklanmıştır:
Stroustrup (1983).
C'nin bazı amaçlarını Classes ile birlikte ele almakta fayda var. Birincil hedef
programların olabildiğince organize edilebileceği bir dil sağlamaktı.
SIMULA 67'de, yani sınıflar ve kalıtımla organize edilmelidir. Bir saniye
önemli amaç, performans ceza ilişkisinin çok az olması veya hiç olmamasıydı.
C'ye bağlı. Örneğin, dizi indeks aralığı kontrolü düşünülmedi bile
çünkü C'ye göre önemli bir performans dezavantajı ortaya çıkacaktır. A
C'nin Classes ile üçüncü hedefi, her uygulama için kullanılabilmesiydi.
hangi C kullanılabilir, bu nedenle C'nin özelliklerinin neredeyse hiçbiri kaldırılmazdı,
güvensiz olarak kabul edilenler bile değil.
1984 yılına gelindiğinde, bu dil sanal yöntemlerin dahil edilmesiyle genişletildi,
yöntem çağrılarının belirli yöntem tanımlarına dinamik olarak bağlanmasını sağlayan,
yöntem adı ve operatör aşırı yüklemesi ve başvuru türleri. Bu sürüm
dil C++ olarak adlandırıldı. Stroustrup'ta (1984) tarif edilmiştir.
1985 yılında, mevcut ilk uygulama ortaya çıktı: adlı bir sistem.
C++ programlarını C programlarına çeviren Cfront. Bu sürüm
Cfront ve uyguladığı C++ sürümü, Sürüm 1.0 olarak adlandırıldı. Bu
Stroustrup'ta (1986) tarif edilmiştir.
1985 ve 1989 arasında, C++ büyük ölçüde kullanıcıya dayalı olarak gelişmeye devam etti.
ilk dağıtılmış uygulamaya tepkiler. Bu sonraki sürümün adı
2.0 sürümü. Cfront uygulaması Haziran 1989'da yayınlandı.
C++ Sürüm 2.0'a eklenen önemli özellikler, çoklu kalıtsal
tance (birden fazla ebeveyn sınıfı olan sınıflar) ve soyut sınıflar ile birlikte
diğer bazı geliştirmeler. Soyut sınıflar Bölüm 12'de açıklanmıştır.
C++'ın 3.0 Sürümü 1989 ile 1990 arasında gelişti. Şablonlar ekledi,
parametreli türler ve istisna işleme sağlar. Mevcut ver-
1998'de standardize edilen C++, ISO'da (1998) açıklanmıştır.

Sayfa 110
2002'de Microsoft, aşağıdakileri içeren .NET bilgi işlem platformunu piyasaya sürdü:
Managed C++ veya MC++ adlı yeni bir C++ sürümü. MC++, C++'ı genişletir
.NET Framework'ün işlevlerine erişim sağlamak için. eklemeler
özellikler, temsilciler, arayüzler ve çöp için bir referans türü içerir.
toplanan nesneler Özellikler Bölüm 11'de tartışılmaktadır. Delegeler kısaca
Bölüm 2.19'daki C# girişinde tartışılmıştır. Çünkü .NET
çoklu kalıtımı destekler, MC++ da desteklemez.
2.16.2 Dile Genel Bakış
C++ hem işlevlere hem de yöntemlere sahip olduğundan, hem yordamsal hem de
nesne yönelimli programlama.
C++'daki operatörler aşırı yüklenebilir, bu da kullanıcının opera-
kullanıcı tanımlı türlerde mevcut operatörler için tors. C++ yöntemleri de olabilir
aşırı yüklenmiş, yani kullanıcı aynı yöntemle birden fazla yöntem tanımlayabilir
parametrelerinin sayıları veya türleri farklı olması koşuluyla, ad.
C++'da dinamik bağlama, sanal yöntemlerle sağlanır. Bu yöntemler
bir koleksiyon içinde aşırı yüklenmiş yöntemler kullanarak türe bağlı işlemleri tanımlayın.
kalıtım yoluyla ilişkili sınıflar. Bir nesneye işaretçi
A sınıfı, ata olarak A sınıfı olan sınıfların nesnelerine de işaret edebilir. Ne zaman
bu işaretçi, aşırı yüklenmiş bir sanal yönteme, mevcut yöntemin yöntemine işaret eder.
tipi dinamik olarak seçilir.
Hem metotlar hem de sınıflar şablonlanabilir, yani
parametreleştirilmiş. Örneğin, bir yöntem şablonlu bir yöntem olarak yazılabilir.
çeşitli parametre türleri için sürümlere sahip olmasını sağlamak için. Sınıfların keyfini çıkarın
aynı esneklik.
C++ çoklu kalıtımı destekler. Ayrıca, istisna işlemeyi de içerir:
Ada'nınkinden önemli ölçüde farklıdır. Bir fark, donanım-
algılanabilir istisnalar ele alınamaz. İstisna işleme yapıları
Ada ve C++, Bölüm 14'te tartışılmaktadır.
2.16.3 Değerlendirme
C++ hızla yaygın olarak kullanılan bir dil haline geldi ve öyle kalmaya devam ediyor. Bir faktör onun
popülerlik, iyi ve ucuz derleyicilerin mevcudiyetidir. Başka bir faktör
C ile neredeyse tamamen geriye dönük olarak uyumlu olmasıdır (yani C
programlar, birkaç değişiklikle C++ programları olarak derlenebilir) ve çoğu
uygulamalarda C++ kodunu C koduyla ilişkilendirmek mümkündür ve böylece
birçok C programcısı için C++ öğrenmesi oldukça kolaydır. Son olarak, C++ zamanında
İlk olarak, nesne yönelimli programlama yaygınlaşmaya başladığında ortaya çıktı.
ilgi, C++ büyük iletişim için uygun olan tek dildi.
ticari yazılım projeleri.
Olumsuz tarafı, C++ çok büyük ve karmaşık bir dil olduğundan,
PL/I'dekine benzer dezavantajlara sahip olduğu açıktır. Çoğunu miras aldı
C'nin Ada ve gibi dillerden daha az güvenli olmasını sağlayan güvensizlikler
Java.
2.16 Zorunlu ve Nesne Yönelimli Özellikleri Birleştirme: C++ 89

Sayfa 111
90
Bölüm 2 Başlıca Programlama Dillerinin Evrimi
2.16.4 İlgili Bir Dil: Amaç-C
Objective-C (Kochan, 2009), her iki impera-
tive ve nesne yönelimli özellikler. Objective-C, Brad Cox tarafından tasarlandı ve
1980'lerin başında Tom Love. Başlangıçta, C artı sınıflardan oluşuyordu ve
Smalltalk'ın mesaj geçişi. Programlama dilleri arasında
nesne yönelimli programlama desteği eklenerek oluşturulur.
tive dili, Objective-C Smalltalk sözdizimini kullanan tek dildir.
bu destek.
Steve Jobs Apple'dan ayrılıp NeXT'yi kurduktan sonra Objective-C'nin lisansını aldı.
ve NeXT bilgisayar sistemi yazılımını yazmak için kullanıldı. ayrıca NeXT
NeXTstep geliştirmesiyle birlikte Objective-C derleyicisini yayınladı
ortam ve bir yardımcı program kütüphanesi. NeXT projesi başarısız olduktan sonra, Apple
NeXT satın aldı ve MAC OS X yazmak için Objective-C'yi kullandı. Objective-C
sonra popülaritesindeki hızlı yükselişini açıklayan tüm iPhone yazılımlarının dili
iPhone göründü.
Objective-C'nin Smalltalk'tan miras aldığı bir özellik,
mesajların nesnelere dinamik olarak bağlanması. Bu, statik olmadığı anlamına gelir.
mesajların kontrol edilmesi. Bir nesneye bir mesaj gönderilirse ve nesne
mesaja yanıt verin, bir istisna olduğunda çalışma zamanına kadar bilinmemektedir.
kabarık.
2006'da Apple, bir tür çöp kutusu ekleyen Objective-C 2.0'ı duyurdu.
özellikleri bildirmek için koleksiyon ve yeni sözdizimi. Ne yazık ki, çöp top-
ders, iPhone çalışma zamanı sistemi tarafından desteklenmez.
Objective-C, C'nin katı bir üst kümesidir, bu nedenle o lan-
guage Objective-C'de mevcuttur.
2.16.5 İlgili Başka Bir Dil: Delphi
Delphi (Lischner, 2000), C++ ve Objetive-C'ye benzer hibrit bir dildir.
diğer şeylerin yanı sıra nesne yönelimli destek eklenerek yaratıldığı için,
mevcut bir zorunlu dile, bu durumda Pascal. Farklılıkların çoğu
C++ ve Delphi arasındaki diller, önceki dillerin bir sonucudur ve
türetildiği çevreleyen programlama kültürleri. çünkü C
güçlü ama potansiyel olarak güvenli olmayan bir dildir, C++ da bu tanıma uyuyor,
en azından dizi alt simge aralığı denetimi, işaretçi aritmetiği ve
sayısız tip zorlamaları. Aynı şekilde, çünkü Pascal daha zarif ve
C'den daha güvenli olan Delphi, C++'dan daha zarif ve daha güvenlidir. Delphi de daha az
C++'dan daha karmaşık. Örneğin, Delphi kullanıcı tanımlı operatöre izin vermez.
aşırı yükleme, genel alt programlar ve parametreli sınıflar, bunların tümü
C++'ın bir parçası.
Delphi, Visual C++ gibi, bir grafik kullanıcı arabirimi (GUI) sağlar.
yazılmış uygulamalara GUI arabirimleri oluşturmanın geliştirici ve basit yolları
Delfi. Delphi, daha önce geliştirmiş olan Anders Hejlsberg tarafından tasarlanmıştır.
Turbo Pascal sistemini çalıştırdı. Bunların her ikisi de tarafından pazarlandı ve dağıtıldı.
Borland. Hejlsberg aynı zamanda C#'ın baş tasarımcısıydı.

Sayfa 112
2.16.6 Gevşek Bağlantılı Bir Dil: Git
Go programlama dili, C++ ile doğrudan ilişkili değildir.
C tabanlı. Kendi bölümünü hak etmediği için kısmen bu bölümde yer almaktadır.
ve başka bir yere sığmaz.
Go, Rob Pike, Ken Thompson ve Robert Griesemer tarafından tasarlanmıştır.
Google. Thompson, C, B'nin selefinin yanı sıra
UNIX'ten Dennis Ritchie ile birlikte tasarımcı. O ve Pike eskiden
Bell Labs'ta çalışıyor İlk tasarım 2007'de başladı ve ilk
uygulama 2009 yılının sonlarında piyasaya sürüldü.
Go, Google'da büyük C++ programlarının derlenmesinin yavaşlığıydı. Biri
Go için ilk derleyicinin özellikleri, son derece hızlı olmasıdır. bu
Go dili, sözdiziminin bir kısmını ödünç alır ve C'den yapılandırır.
Go'nun yeni özellikleri şunları içerir: (1) Veri bildirimleri sözdizimseldir
diğer C tabanlı dillerden tersine çevrilmiştir; (2) değişkenler türden önce gelir
isim; (3) değişken tanımlıysa, değişken bildirimlerine çıkarım yoluyla bir tür verilebilir.
bir başlangıç ​​değeri verilir; ve (4) işlevler birden çok değer döndürebilir. git olmaz
hiçbir kalıtsal biçimi olmadığı için geleneksel nesne yönelimli programlamayı destekler.
tans. Ancak, herhangi bir tür için yöntemler tanımlanabilir. Ayrıca sahip değil
jenerik. Go'nun kontrol ifadeleri, diğer C-tabanlı
diller, anahtar, örtük düşmeyi içermese de
sonraki bölüm. Go bir goto ifadesi, işaretçiler, ilişkisel diziler içerir,
arabirimler (Java ve C#'dan farklı olsalar da) ve destek
goroutinlerini kullanarak eşzamanlılık için.
2.17 Zorunlu Tabanlı Nesne Yönelimli Bir Dil: Java
Java'nın tasarımcıları C++ ile başladılar, bazı yapıları kaldırdılar, bazılarını değiştirdiler ve
birkaç tane daha ekledi. Ortaya çıkan dil, gücün çoğunu sağlar ve
C++'ın esnekliği, ancak daha küçük, daha basit ve daha güvenli bir dilde.
2.17.1 Tasarım Süreci
Java, birçok programlama dili gibi, bir uygulama için tasarlanmıştır.
tatmin edici bir mevcut dil olmadığı ortaya çıktı. 1990 yılında Güneş
Mikrosistemler, bir programlama diline ihtiyaç olduğunu belirledi.
tost makineleri, mikrodalga fırınlar gibi gömülü tüketici elektroniği cihazları ve
interaktif TV sistemleri. Güvenilirlik, böyle bir sistem için birincil hedeflerden biriydi.
dilim. güvenilirliğin önemli bir faktör olmayacağı görünebilir.
mikrodalga fırın için yazılım. Bir fırının arızalı yazılımı varsa,
ustaca kimse için ciddi bir tehlike oluşturmaz ve büyük olasılıkla yol açmaz
büyük yasal anlaşmalar için. Ancak, belirli bir modeldeki yazılım
bir milyon adet üretilip satıldıktan sonra hatalı olduğu tespit edildi,
geri çağırmaları önemli bir maliyet gerektirecektir. Bu nedenle, güvenilirlik olan önemli
Tüketici elektroniği ürünlerinde yazılımın karakteristiği.
2.17 Zorunlu Tabanlı Nesne Yönelimli Bir Dil: Java 91

Sayfa 113
92
Bölüm 2 Başlıca Programlama Dillerinin Evrimi
C ve C++ ele alındıktan sonra ikisinin de satılmayacağına karar verildi.
Tüketici elektroniği cihazları için yazılım geliştirmek için fabrika. Rağmen
C nispeten küçüktü, nesne yönelimli pro-
bir gereklilik olarak gördükleri gramer. C++ destekli nesne yönelimli
programlama, ancak kısmen çünkü çok büyük ve karmaşık olduğuna karar verildi.
ayrıca prosedür odaklı programlamayı da destekledi. Ayrıca inanılıyordu
ne C ne de C++ gerekli güvenilirlik seviyesini sağlamadı. Yani, yeni bir lan-
daha sonra Java olarak adlandırılan guage tasarlandı. Tasarımı eğlence tarafından yönlendirildi.
C++'dan daha fazla basitlik ve güvenilirlik sağlamanın temel amacı,
sağlayacağına inanılır.
Java için ilk itici güç tüketici elektroniği olmasına rağmen, hiçbiri
ilk yıllarında birlikte kullanıldığı ürünler piyasaya sürülmüştür. Başlangıç
1993 yılında, World Wide Web yaygın olarak kullanılmaya başlandığında ve büyük ölçüde
Yeni grafik tarayıcılardan Java'nın Web pro-
gramer. Özellikle, nispeten küçük Java programları olan Java uygulamaları
Web tarayıcılarında yorumlanan ve çıktısı aşağıdakilere dahil edilebilen
görüntülenen Web belgeleri, orta ila geç arasında hızla çok popüler oldu
1990'lar. Java popülaritesinin ilk birkaç yılında, Web en yaygın olanıydı.
uygulama.
Java tasarım ekibine, daha önce
UNIX emacs düzenleyicisini ve NeWS pencereleme sistemini tasarladı.
2.17.2 Dile Genel Bakış
Daha önce de belirttiğimiz gibi Java, C++ tabanlıdır ancak özel olarak tasarlanmıştır.
daha küçük, daha basit ve daha güvenilir olmak. C++ gibi Java'nın da hem sınıfları hem de
ilkel tipler. Java dizileri önceden tanımlanmış bir sınıfın örnekleridir, oysa C++
değiller, ancak birçok C++ kullanıcısı dizilerin eklenmesi için sarmalayıcı sınıfları oluştursa da
Java'da örtük olan dizin aralığı denetimi gibi özellikler.
Java'nın işaretçileri yoktur, ancak başvuru türleri bazı özellikleri sağlar.
işaretçilerin yetenekleri. Bu referanslar, sınıf örneklerine işaret etmek için kullanılır.
Tüm nesneler öbek üzerinde tahsis edilir. Referanslar her zaman dolaylı olarak
gerektiğinde gerçekleştirildi. Böylece daha çok sıradan skaler değişkenler gibi davranırlar.
Java, boolean adlı ilkel bir Boole türüne sahiptir ve çoğunlukla
kontrol ifadelerinin kontrol ifadeleri (örneğin if ve while ). C'den farklı olarak
ve C++, aritmetik ifadeler kontrol ifadeleri için kullanılamaz.
Java ile öncüllerinin çoğu arasındaki önemli bir fark,
C++ dahil olmak üzere nesne yönelimli programlamayı desteklemek, bunun mümkün olmamasıdır.
Java'da bağımsız alt programlar yazmak için. Tüm Java alt programları yöntemlerdir
ve sınıflarda tanımlanır. Ayrıca, yöntemler bir sınıf aracılığıyla çağrılabilir.
veya yalnızca nesne. Bunun bir sonucu, C++ her iki pro-
sedural ve nesne yönelimli programlama, Java, nesne yönelimli pro-
sadece gramer
C++ ve Java arasındaki bir diğer önemli fark, C++'ın desteklemesidir.
doğrudan sınıf tanımlarında çoklu kalıtım. Java yalnızca tek

Sayfa 114
sınıfların kalıtımı, ancak çoklu kalıtımın bazı faydaları olabilir
arayüz yapısı kullanılarak elde edilebilir.
Java'ya kopyalanmayan C++ yapıları arasında yapılar ve
sendikalar.
Java, nispeten basit bir eşzamanlılık denetimi biçimi içerir.
yöntemler ve bloklarda görünebilen senkronize değiştirici. ikisinde de
durumda, bir kilidin takılmasına neden olur. Kilit, karşılıklı olarak özel erişim sağlar
veya yürütme. Java'da, eşzamanlı süreçler oluşturmak nispeten kolaydır;
Java'da iş parçacığı denir .
Java, genellikle çöp olarak adlandırılan nesneleri için örtük depolama tahsisini kullanır
koleksiyon . Bu, programcıyı nesneleri açıkça silme ihtiyacından kurtarır
artık ihtiyaç duymadıklarında. olmayan dillerde yazılmış programlar
çöp toplama genellikle bazen bellek denilen şeyden muzdarip
sızıntı, bu, depolamanın tahsis edildiği ancak hiçbir zaman serbest bırakılmadığı anlamına gelir. Bu
açık bir şekilde mevcut tüm depolamanın nihai olarak tükenmesine yol açar. Nesne ayırma
Bölüm 6'da ayrıntılı olarak tartışılmaktadır.
C ve C++'dan farklı olarak Java, atama türü zorlamaları içerir (örtük tip
dönüşümler) yalnızca genişliyorlarsa ("daha küçük" türden "daha büyük" bir türe).
Bu nedenle, int to float zorlamaları atama operatörü boyunca yapılır, ancak float
için int zorlamalarının değildir.
2.17.3 Değerlendirme
Java tasarımcıları, aşırı ve/veya güvenli olmayan özellikleri kırpmakta başarılı oldular.
C++. Örneğin, atama zorlamalarının yarısının ortadan kaldırılması
C++ ile yapılanlar açıkça daha yüksek güvenilirliğe doğru bir adımdı. dizin aralığı
dizi erişimlerinin kontrol edilmesi de dili daha güvenli hale getirir. Ek olarak
eşzamanlılık, yazılabilen uygulamaların kapsamını geliştirir
grafiksel kullanıcı arayüzleri, veritabanı erişimi,
ve ağ oluşturma.
Java'nın taşınabilirliği, en azından ara formda, genellikle
dilin tasarımına, ama değil. Herhangi bir dile çevrilebilir
bir ara form ve sanal makineye sahip herhangi bir platformda "çalıştır"
bu ara form için. Bu tür taşınabilirliğin fiyatı,
geleneksel olarak daha çok bir büyüklük sırası hakkında olan yorum
makine kodunun yürütülmesinden daha fazla. Java yorumlayıcısının ilk sürümü,
Java Sanal Makinesi (JVM) olarak adlandırılan, gerçekten de en az 10 kat daha yavaştı
eşdeğer derlenmiş C programlarından daha fazla. Ancak, birçok Java programı artık
Tam Zamanında (JIT) kullanılarak yürütülmeden önce makine koduna çevrildi
derleyiciler. Bu, Java programlarının verimliliğini, Java programlarının verimliliğiyle rekabet edebilir hale getirir.
C++ gibi geleneksel olarak derlenmiş dillerdeki programlar.
Java kullanımı diğer tüm programlama dillerinden daha hızlı arttı.
ölçü. Başlangıçta bunun nedeni dinamik Web belgelerinin programlanmasındaki değeriydi.
mentler. Açıkçası, Java'nın hızla öne çıkmasının nedenlerinden biri basitçe
programcıların tasarımını beğendiğini gösterir. Bazı geliştiriciler C++'ın çok basit olduğunu düşündü
2.17 Zorunlu Tabanlı Nesne Yönelimli Bir Dil: Java 93

Sayfa 115
94
Bölüm 2 Başlıca Programlama Dillerinin Evrimi
pratik ve güvenli olması için büyük ve karmaşık. Java onlara bir alternatif sundu
C++'ın gücünün çoğuna sahiptir, ancak daha basit, daha güvenli bir dilde. Diğer sebep
Java için derleyici/tercüman sisteminin ücretsiz olması ve
ağ. Java artık çeşitli farklı uygulama alanlarında yaygın olarak kullanılmaktadır.
Java'nın en son sürümü olan Java 7, 2011'de ortaya çıktı.
ning, bir numaralandırma da dahil olmak üzere dile birçok özellik eklendi.
sınıf, jenerikler ve yeni bir yineleme yapısı.
Aşağıda bir Java programı örneği verilmiştir:
// Java Örnek Programı
// Giriş: listlen'in daha az olduğu bir tamsayı, listlen
//
100'den fazla, ardından uzunluk-tamsayı değerleri
// Çıktı: Şundan büyük olan girdi verilerinin sayısı
//
tüm girdi değerlerinin ortalaması
java.io'yu içe aktar *;
sınıf IntSort {
public static void main(String args[]) IOException { öğesini atar
DataInputStream in = new DataInputStream(System.in);
int dinle,
tezgah,
toplam = 0,
ortalama,
sonuç = 0;
int [] intlist = yeni int [99];
listlen = Integer.parseInt(in.readLine());
if ((listlen > 0) && (listlen < 100)) {
/* Girdiyi bir diziye oku ve toplamını hesapla */
for (sayaç = 0; sayaç < listlen; sayaç++) {
intlist[sayaç] =
Integer.valueOf(in.readLine()).intValue();
toplam += intlist[sayaç];
}
/* Ortalamayı hesapla */
ortalama = toplam / dinle;
/* > ortalama olan giriş değerlerini sayın */
for (sayaç = 0; sayaç < listlen; sayaç++)
if (intlist[sayaç] > ortalama) sonuç++;
/* Sonucu yazdır */
System.out.println(
"\nDeğer sayısı > ortalama:" + sonuç);
} //** if cümlesinin sonu ((listlen > 0) ...
başka System.out.println(
"Hata—giriş listesi uzunluğu yasal değil\n");
} //** ana yöntemin sonu
} //** sınıfın sonu IntSort

Sayfa 116
2.18 Komut Dosyası Dilleri
Komut dosyası dilleri son 25 yılda gelişti. Erken komut dosyası
diller, bir dosyaya komut dosyası adı verilen bir komut listesi koyarak kullanıldı.
yorumlanacak. Bu dillerden sh (kabuk için) adlı ilki başladı.
sisteme yapılan çağrılar olarak yorumlanan küçük bir komut koleksiyonu olarak
dosya yönetimi gibi yardımcı işlevler gerçekleştiren alt programlar ve
basit dosya filtreleme. Buna değişkenler, kontrol akışı ifadeleri,
fonksiyonlar ve çeşitli diğer yetenekler ve sonuç tam bir pro-
gramer dili. Bunların en güçlülerinden ve yaygın olarak bilinenlerinden biri
olduğu Ksh Bell David Korn tarafından geliştirilen (Bolsky ve Korn, 1995),
Laboratuvarlar.
Başka betik dilidir awk Al Aho Brian Kernighan tarafından geliştirilen,
ve Peter Weinberger, Bell Laboratories'de (Aho ve diğerleri, 1988). awk olarak başladı
rapor oluşturma dili, ancak daha sonra daha genel amaçlı bir dil haline geldi.
2.18.1 Perl'in Kökenleri ve Özellikleri
Larry Wall tarafından geliştirilen Perl dili, başlangıçta bir kombinasyondu.
arasında sh ve awk . Perl başlangıcından bu yana önemli ölçüde büyüdü ve şimdi bir
güçlü, ancak yine de biraz ilkel, programlama dili. Rağmen
hala genellikle bir betik dili olarak adlandırılır, aslında tipik bir betik diline daha benzer.
zorunlu dil, her zaman derlendiğinden, en azından bir ara
dil, yürütülmeden önce. Ayrıca, yapmak için tüm yapılara sahiptir
çok çeşitli hesaplama problemlerine uygulanabilir.
Perl'in bir dizi ilginç özelliği vardır, bunlardan sadece birkaçı erkektir.
Bu bölümde bahsedilmiş ve daha sonra kitapta tartışılmıştır.
Perl'deki değişkenler statik olarak yazılır ve dolaylı olarak bildirilir. Var
değişkenler için ilk karakterle gösterilen üç ayırt edici ad alanı
değişkenlerin isimleri. Tüm skaler değişken adları dolar işaretiyle ( $ ) başlar, tümü
dizi adları @ işaretiyle başlar ve tüm karma adları (karmalar kısaca
aşağıda açıklanan) yüzde işaretleri ( % ) ile başlar . Bu sözleşme çeşitli
programlardaki diğer programlardan daha okunabilir isimler
dilim.
Perl, çok sayıda örtük değişken içerir. Bazıları kullanılır
yeni satır karakterinin belirli biçimi gibi Perl parametrelerini depolamak veya
uygulamada kullanılan karakterler. Örtük değişkenler
monly yerleşik işlevler ve varsayılan işlenenler için varsayılan parametreler olarak kullanılır
Bazı operatörler için. Örtük değişkenlerin ayırt edici özellikleri vardır - şifreli olsalar da -
$ gibi isimler ! ve @_ . Kullanıcı tanımlı gibi örtük değişkenlerin adları
değişken adları için üç ad alanını kullanın, bu nedenle $! bir skalerdir.
Perl dizilerinin, onları dizilerden ayıran iki özelliği vardır.
ortak zorunlu dillerden biridir. İlk olarak, dinamik uzunlukları vardır, ortalama-
yürütme sırasında gerektiği gibi büyüyüp küçülebilirler. İkincisi, diziler
seyrek olabilir, yani öğeler arasında boşluklar olabilir. Bunlar
2.18 Komut Dosyası Dilleri 95

Sayfa 117
96
Bölüm 2 Başlıca Programlama Dillerinin Evrimi
boşluklar bellekte yer kaplamaz ve diziler için kullanılan yineleme ifadesi,
foreach , eksik öğeler üzerinde yinelenir.
Perl, karma olarak adlandırılan ilişkisel dizileri içerir . Bu veri yapıları-
tures diziler tarafından indekslenir ve dolaylı olarak kontrol edilen hash tablolarıdır. Perl
sistem, hash fonksiyonunu sağlar ve yapının boyutunu büyütür.
gerekli.
Perl güçlü ama biraz tehlikeli bir dildir. Onun skaler tip mağazaları
normalde çift duyarlıklı kayan sistemde depolanan hem dizeler hem de sayılar
nokta formu. Bağlama bağlı olarak, sayılar dizelere zorlanabilir ve
tersine. Sayısal bağlamda bir dize kullanılıyorsa ve dize dönüştürülemiyorsa
bir sayıya sıfır kullanılır ve herhangi bir uyarı veya hata mesajı verilmez
kullanıcı için. Bu etki, derleyici tarafından algılanmayan hatalara yol açabilir.
veya çalışma zamanı sistemi. Dizi indeksleme kontrol edilemiyor çünkü set yok
herhangi bir dizi için alt simge aralığı. Var olmayan öğelere yapılan başvurular undef değerini döndürür ,
sayısal bağlamda sıfır olarak yorumlanır. Dolayısıyla herhangi bir hata tespiti de söz konusu değildir.
dizi öğesi erişiminde tion.
Perl'in ilk kullanımı, metin dosyalarını işlemek için bir UNIX yardımcı programıydı. öyleydi ve
hala bir UNIX sistem yönetim aracı olarak yaygın olarak kullanılmaktadır. ne zaman dünya
Geniş Ağ ortaya çıktı, Perl bir Ortak Ağ Geçidi olarak yaygın bir kullanıma kavuştu
Şimdi nadiren bunun için kullanılmasına rağmen, Web ile kullanım için arayüz dili
amaç. Perl, çeşitli uygulamalar için genel amaçlı bir dil olarak kullanılır,
hesaplamalı biyoloji ve yapay zeka gibi.
Aşağıda bir Perl programı örneği verilmiştir:
# Perl Örnek Programı
# Girdi: $listlen'ın daha az olduğu bir tamsayı, $listlen
#
100'den fazla, ardından $listlen-integer değerleri.
# Çıkış: Şundan büyük giriş değerlerinin sayısı
#
tüm girdi değerlerinin ortalaması.
($toplam, $sonuç) = (0, 0);
$listlen = <STDIN>;
if (($listlen > 0) && ($listlen < 100)) {
# Girdiyi bir diziye oku ve toplamı hesapla
for ($sayaç = 0; $sayaç < $listlen; $sayaç++) {
$intlist[$counter] = <STDIN>;
} #- for sonu (sayaç ...
# Ortalamayı hesapla
$ortalama = $toplam / $listlen;
# > ortalama olan giriş değerlerini sayın
foreach $num (@intlist) {
if ($sayı > $ortalama) { $sonuç++; }
} #- foreach $sayısının sonu ...
# Baskı sonucu
print "Değer sayısı > ortalama: $sonuç \n";
} #- if'nin sonu (($listlen ...

Sayfa 118
başka {
print "Hata--giriş listesi uzunluğu yasal değil \n";
}
2.18.2 JavaScript'in Kökenleri ve Özellikleri
Web'in kullanımı, ilk grafik tarayıcılardan sonra 1990'ların ortalarında patladı.
ortaya çıktı. HTML belgeleriyle ilişkili hesaplama ihtiyacı,
kendi başlarına tamamen statik, hızla kritik hale geldi. Hesaplama açık
Sunucu tarafı, Ortak Ağ Geçidi Arayüzü (CGI) ile mümkün hale getirildi,
HTML belgelerinin programların yürütülmesini talep etmesine izin veren
sunucu, bu tür hesaplamaların sonuçları ile tarayıcıya döndürülür.
HTML belgelerinin biçimi. Tarayıcı tarafında hesaplama oldu
Java uygulamalarının gelişiyle kullanılabilir. Bu yaklaşımların her ikisi de şimdi
çoğunlukla komut dosyası oluşturma olmak üzere daha yeni teknolojilerle değiştirildi
Diller.
JavaScript (Flanagan, 2002) orijinal olarak Brendan Eich tarafından geliştirilmiştir.
Netscape. Orijinal adı Mocha idi. Daha sonra LiveScript olarak yeniden adlandırıldı. Geç zamanda
1995, LiveScript, Netscape ve Sun Microsystems'in ortak girişimi oldu
ve adı JavaScript olarak değiştirildi. JavaScript kapsamlı geçti
evrim, birçok yeni özellik ekleyerek 1.0 sürümünden 1.5 sürümüne geçiş
özellikler ve yetenekler. JavaScript için bir dil standardı geliştirildi.
1990'ların sonlarında Avrupa Bilgisayar Üreticileri Birliği (ECMA) tarafından
ECMA-262. Bu standart aynı zamanda Uluslararası Standartlar tarafından da onaylanmıştır.
Dards Organizasyonu (ISO), ISO-16262 olarak. Microsoft'un JavaScript sürümü
JScript .NET olarak adlandırılır.
Bir JavaScript yorumlayıcısı birçok farklı
uygulamalar, en yaygın kullanımı Web tarayıcılarına gömülüdür. JavaScript
kodu HTML belgelerine gömülür ve tarayıcı tarafından yorumlanır.
belgeler görüntülenir. JavaScript'in Web programında birincil kullanımları-
ming, form giriş verilerini doğrulamak ve dinamik HTML belgeleri oluşturmak içindir.
JavaScript ayrıca artık Rails Web geliştirme çerçevesiyle birlikte kullanılmaktadır.
Adına rağmen JavaScript, Java ile yalnızca kullanım yoluyla ilişkilidir.
benzer sözdizimi. Java kesinlikle yazılmıştır, ancak JavaScript dinamik olarak yazılmıştır
(bkz. Bölüm 5). JavaScript'in karakter dizileri ve dizileri dinamik
uzunluk. Bu nedenle, dizi indekslerinin geçerliliği kontrol edilmez, ancak
bu Java'da gereklidir. Java, nesne yönelimli programlamayı tamamen destekler, ancak
JavaScript, yöntem çağrılarının ne devralmasını ne de dinamik bağlanmasını destekler
yöntemlere.
JavaScript'in en önemli kullanımlarından biri dinamik olarak oluşturmak içindir.
ve HTML belgelerini değiştirme. JavaScript bir nesne hiyerarşisi tanımlar.
tarafından tanımlanan bir HTML belgesinin hiyerarşik modeliyle eşleşir.
Belge Nesne Modeli. Bir HTML belgesinin öğelerine erişilir
öğelerin dinamik kontrolü için temel sağlayan bu nesneler aracılığıyla
belgeler.
2.18 Komut Dosyası Dilleri 97

Sayfa 119
98
Bölüm 2 Başlıca Programlama Dillerinin Evrimi
Aşağıda, daha önce birkaç şekilde çözülen sorun için bir JavaScript betiği verilmiştir.
Bu bölümdeki diller. Bu betiğin çağrılacağının varsayıldığını unutmayın.
bir HTML belgesinden alınır ve bir Web tarayıcısı tarafından yorumlanır.
// örnek.js
// Giriş: listLen'in daha az olduğu bir tamsayı, listLen
//
100'den fazla, ardından listLen sayısal değerler
// Çıktı: Daha büyük olan girdi değerlerinin sayısı
//
tüm girdi değerlerinin ortalamasından
var intList = new Array(99);
var listLen, sayaç, toplam = 0, sonuç = 0;
listLen = komut istemi (
"Lütfen giriş listesinin uzunluğunu yazın", "");
if ((listLen > 0) && (listLen < 100)) {
// Girdiyi alın ve toplamını hesaplayın
for (sayaç = 0; sayaç < listLen; sayaç++) {
intList[sayaç] = komut istemi (
"Lütfen sonraki numarayı yazın", "");
toplam += parseInt(intList[sayaç]);
}
// Ortalamayı hesapla
ortalama = toplam / listeLen;
// > ortalama olan giriş değerlerini sayın
for (sayaç = 0; sayaç < listLen; sayaç++)
if (intList[sayaç] > ortalama) sonuç++;
// Sonuçları göster
document.write("Değer sayısı > ortalama: ",
sonuç, "<br />");
} başka
belge.yaz(
"Hata - giriş listesi uzunluğu yasal değil <br />");
2.18.3 PHP'nin Kökenleri ve Özellikleri
PHP (Converse ve Park, 2000), bir üye olan Rasmus Lerdorf tarafından geliştirilmiştir.
1994'te Apache Grubu'nun bir üyesiydi. İlk motivasyonu,
kişisel Web sitesine gelen ziyaretçilerin izlenmesine yardımcı olur. 1995 yılında bir paket geliştirdi.
İlk halka açık hale gelen Kişisel Ana Sayfa Araçları olarak adlandırılan
PHP'nin sürümü. Başlangıçta PHP, Kişisel Ana Sayfa'nın kısaltmasıydı.
Daha sonra, kullanıcı topluluğu PHP: Köprü Metni özyinelemeli adını kullanmaya başladı.

sayfa 120
Daha sonra orijinal adı belirsizliğe zorlayan önişlemci. PHP
artık açık kaynaklı bir ürün olarak geliştirilmekte, dağıtılmakta ve desteklenmektedir. PHP
işlemciler çoğu Web sunucusunda yerleşiktir.
PHP, özellikle HTML gömülü bir sunucu tarafı betik dilidir.
Web uygulamaları için tasarlanmıştır. PHP kodu Web sunucusunda yorumlanır
gömülü olduğu bir HTML belgesi bir kişi tarafından istendiğinde
tarayıcı. PHP kodu genellikle çıktı olarak HTML kodunu üretir ve bunun yerini alır.
HTML belgesindeki PHP kodu. Bu nedenle, bir Web tarayıcısı asla
PHP kodu.
PHP, JavaScript'e benzer, sözdizimsel görünümünde dinamiktir.
dizelerinin ve dizilerinin doğası ve dinamik yazmanın kullanımı. PHP'nin dizileri
JavaScript dizilerinin ve Perl'in karmalarının bir kombinasyonu.
PHP'nin orijinal sürümü, nesne yönelimli programları desteklemiyordu.
ming, ancak bu destek ikinci sürümde eklendi. Ancak, PHP yapar
için soyut sınıfları veya arayüzleri, yıkıcıları veya erişim kontrollerini desteklemez.
sınıf üyeleri.
PHP, HTML form verilerine basit erişim sağlar, bu nedenle form işleme kolaydır
PHP ile. PHP birçok farklı veritabanı yönetimi için destek sağlar
sistemler. Bu, onu Web'e ihtiyaç duyan programlar oluşturmak için kullanışlı bir dil yapar.
veritabanlarına erişim.
2.18.4 Python'un Kökenleri ve Özellikleri
Python (Lutz ve Ascher, 2004) nispeten yeni bir nesne yönelimli inter-
önceden hazırlanmış betik dili. İlk tasarımı Guido van Rossum tarafından yapılmıştır.
1990'ların başında Hollanda'da Stichting Mathematisch Centrum. Onun
geliştirme şu anda Python Yazılım Vakfı tarafından yapılıyor. piton
Perl ile aynı türden uygulamalar için kullanılıyor: sistem yönetimi,
CGI programlama ve diğer nispeten küçük bilgi işlem görevleri. Python bir
açık kaynaklı sistemdir ve en yaygın bilgi işlem platformları için mevcuttur.
Python uygulaması şurada mevcuttur: www.python.org , ayrıca
Python ile ilgili kapsamlı bilgiler.
Python'un sözdizimi, doğrudan yaygın olarak kullanılan herhangi bir dile dayalı değildir. Bu
kontrol edildi, ancak dinamik olarak yazıldı. Python, diziler yerine üç
veri yapıları türleri: listeler; tuple adı verilen değişmez listeler ; ve
sözlükler olarak adlandırılan karmalar . Liste yöntemlerinin bir koleksiyonu var,
gibi , ekleme yapılması , ekin , kaldır ve sıralama meth- ait yanı sıra bir koleksiyon
anahtarlar , değerler , kopya ve has_key gibi sözlükler için ods . Python ayrıca
Haskell dilinden kaynaklanan liste anlamalarını destekler. Liste
kavramalar Bölüm 15.8'de tartışılmaktadır.
Python nesne yönelimlidir, model eşleştirme yeteneklerini içerir.
Perl ve istisna işlemeye sahiptir. Çöp toplama, nesneleri geri almak için kullanılır
artık ihtiyaç duymadıklarında.
CGI programlama ve özellikle form işleme desteği pro-
cgi modülü tarafından görüntülendi . Tanımlama bilgilerini, ağ oluşturmayı ve verileri destekleyen modüller
baz erişim de mevcuttur.
2.18 Komut Dosyası Dilleri 99

Sayfa 121
100
Bölüm 2 Başlıca Programlama Dillerinin Evrimi
Python, iş parçacıklarıyla eşzamanlılık desteğinin yanı sıra destek içerir.
soketleri ile ağ programlama için bağlantı noktası. Ayrıca daha fazla desteği var
Fonksiyonel programlama, diğer fonksiyonel olmayan programlama dillerinden daha iyidir.
Python'un daha ilginç özelliklerinden biri, kolayca
herhangi bir kullanıcı tarafından genişletildi. Uzantıları destekleyen modüller yazılabilir
herhangi bir derlenmiş dilde. Uzantılar işlevler, değişkenler ve nesne ekleyebilir
türleri. Bu uzantılar, Python yorumlayıcısına eklemeler olarak uygulanır.
2.18.5 Ruby'nin Kökenleri ve Özellikleri
Ruby (Thomas ve diğerleri, 2005) Yukihiro Matsumoto (namı diğer Matz) tarafından ABD'de tasarlanmıştır.
1990'ların başında ve 1996'da piyasaya sürüldü. O zamandan beri sürekli olarak gelişti. bu
Ruby'nin motivasyonu, tasarımcısının Perl ve Python ile ilgili memnuniyetsizliğiydi.
Hem Perl hem de Python nesne yönelimli programlamayı desteklese de, 14 nei-
saf nesne yönelimli bir dil vardır, en azından her birinin ilkel olması anlamında.
tive (nesne olmayan) türleri ve her biri işlevleri destekler.
Ruby'nin birincil karakterize edici özelliği, saf bir nesne olmasıdır.
Smalltalk'ta olduğu gibi odaklı bir dil. Her veri değeri bir nesnedir ve hepsi
işlemler metot çağrıları ile yapılır. Ruby'deki operatörler yalnızca sözdizimseldir
ilgili işlemler için yöntem çağrılarını belirtmek için mekanizmalar. Çünkü
bunlar yöntemlerdir, yeniden tanımlanabilirler. Tüm sınıflar, ön tanımlı veya kullanıcı tanımlı,
alt sınıflanabilir.
Ruby'deki hem sınıflar hem de nesneler, yöntemlerin yapabileceği anlamda dinamiktir.
ikisine de dinamik olarak eklenebilir. Bu, hem sınıfların hem de nesnelerin
yürütme sırasında farklı zamanlarda farklı yöntem kümelerine sahiptir. Çok farklı
aynı sınıfın örnekleri farklı davranabilir. Yöntem koleksiyonları,
veriler ve sabitler bir sınıfın tanımına dahil edilebilir.
Ruby'nin sözdizimi, Eiffel ve Ada'nınkiyle ilişkilidir. Gerek yoktur
değişkenleri bildirmek için, çünkü dinamik yazma kullanılır. Bir değişkenin kapsamı
adında belirtilir: Adı bir harfle başlayan bir değişkenin yerel
dürbün; @ ile başlayan bir örnek değişkendir; $ ile başlayan biri
küresel kapsamı vardır. Ruby'de Perl'in bir dizi özelliği mevcuttur.
$_ gibi saçma isimlere sahip örtük değişkenler .
Python'da olduğu gibi, herhangi bir kullanıcı Ruby'yi genişletebilir ve/veya değiştirebilir. yakut
tasarlanan ilk programlama dili olduğu için kültürel açıdan ilginçtir.
Japonya'da, Amerika Birleşik Devletleri'nde nispeten yaygın bir kullanıma kavuşmuştur.
2.18.6 Lua'nın Kökenleri ve Özellikleri
Lua 15 , 1990'ların başında Roberto Ierusalimschy, Waldemar tarafından tasarlandı.
Celes ve Luis Henrique de Figueiredo, Rio Pontifical Üniversitesi'nde
Brezilya'da de Janeiro. Prosedürel ve destekleyici bir betik dilidir.
14. Aslında, Python'un nesne yönelimli programlama desteği kısmidir.
15. Lua adı Portekizce ay anlamına gelen kelimeden türetilmiştir.

Sayfa 122
birincil hedeflerinden biri olarak genişletilebilirlik ile işlevsel programlama. Arasında
tasarımını etkileyen diller Scheme, Icon ve Python'dur.
Lua, nesne yönelimliliği desteklemediği için JavaScript'e benzer.
ama açıkça ondan etkilenmişti. Her ikisinde de oynayan nesneler var
hem sınıfların hem de nesnelerin rolü ve her ikisinin de prototip mirası vardır.
sınıf mirasından daha fazla. Ancak, Lua'da dil, aşağıdakileri kapsayacak şekilde genişletilebilir:
port nesne yönelimli programlama.
Şemada olduğu gibi, Lua'nın fonksiyonları birinci sınıf değerlerdir. Ayrıca, Lua destekler
kapanışlar. Bu yetenekler, işlevsel programlama için kullanılmasına izin verir.
Ayrıca Scheme gibi, Lua'nın da yalnızca tek bir veri yapısı vardır, ancak Lua'nın durumunda,
o masa. Lua'nın tabloları, PHP'nin aşağıdakileri kapsayan ortak dizilerini genişletir.
geleneksel zorunlu dillerin dizileri. Tablo öğelerine yapılan referanslar
geleneksel dizilere, ilişkisel dizilere veya kayıtlara referans şeklini alır.
Fonksiyonlar birinci sınıf değerler olduğu için tablolarda saklanabilir ve bu tür
tablolar ad alanları olarak hizmet verebilir.
Lua, tümü yığın tahsisli olan nesneleri için çöp toplamayı kullanır. o
diğer komut dosyası dillerinin çoğunda olduğu gibi dinamik yazmayı kullanır.
Lua, nispeten küçük ve basit bir dildir, yalnızca 21'i ayrılmıştır.
sözler. Dilin tasarım felsefesi, çıplak temelleri sağlamaktı.
ve çeşitli dillere uymasını sağlamak için dili genişletmenin nispeten basit yolları.
uygulama alanları. Genişletilebilirliğinin çoğu, tablo veri yapısından kaynaklanmaktadır.
Lua'nın metatable konsepti kullanılarak özelleştirilebilir.
Lua, diğer dillere bir betik dili uzantısı olarak rahatlıkla kullanılabilir.
Diller. Java'nın ilk uygulamaları gibi, Lua da bir ara-araya çevrilmiştir.
kodlanmış ve yorumlanmıştır. Kolayca diğer sistemlere kolayca gömülebilir,
kısmen, yalnızca yaklaşık 150K olan yorumlayıcısının küçük boyutu nedeniyle
bayt.
2006 ve 2007 boyunca, Lua'nın popülaritesi, kısmen
oyun endüstrisinde kullanımı. sahip olan betik dillerinin sırası
son 20 yılda ortaya çıkan, yaygın olarak kullanılan birkaç lan-
göstergeler. Aralarında en son gelen Lua, hızla bir oluyor.
2.19 Amiral Gemisi .NET Dili: C#
C#, yeni geliştirme platformu .NET ile birlikte 16 tarafından duyuruldu.
2000 yılında Microsoft. Ocak 2002'de her ikisinin de üretim sürümleri yayınlandı.
2.19.1 Tasarım Süreci
C#, C++ ve Java'yı temel alır ancak Delphi ve Visual'den bazı fikirler içerir.
TEMEL. Baş tasarımcısı Anders Hejlsberg, Turbo Pascal'ı da tasarladı ve
C# mirasının Delphi kısımlarını açıklayan Delphi.
16. .NET geliştirme sistemi Bölüm 1'de kısaca tartışılmaktadır.
2.19 Amiral Gemisi .NET Dili: C# 101

Sayfa 123
102
Bölüm 2 Başlıca Programlama Dillerinin Evrimi
C#'ın amacı, bileşen tabanlı yazılım için bir dil sağlamaktır.
geliştirme, özellikle .NET Framework'teki bu tür geliştirmeler için. İçinde
bu ortamda, çeşitli dillerden bileşenler kolayca
sistemler oluşturmak için birleştirilir. C#, Visual dahil tüm .NET dilleri
Temel .NET, Yönetilen C++, F# ve JScript .NET, 17 Ortak Türü kullanır
Sistem (CTS). CTS, ortak bir sınıf kitaplığı sağlar. Tüm türler beşte
.NET dilleri, tek bir sınıf kökü olan System.Object'den devralır . derleyiciler
CTS spesifikasyonuna uyan, birleştirilebilen nesneler yaratır.
yazılım sistemleri. Tüm .NET dilleri aynı aracı içinde derlenir.
yedi formu, Orta Dil (IL). 18 Ancak Java'dan farklı olarak, IL hiçbir zaman
yorumlandı. IL'yi makine koduna çevirmek için bir Tam Zamanında derleyici kullanılır
yürütülmeden önce.
2.19.2 Dile Genel Bakış
Birçoğu, Java'nın C++ üzerindeki en önemli gelişmelerinden birinin,
C++'ın bazı özelliklerini içermediği gerçeği. Örneğin, C++ birden çok
kalıtım, işaretçiler, yapılar, numaralandırma türleri, operatör aşırı yüklemesi ve bir goto
ancak Java bunların hiçbirini içermez. Açıkçası C# tasarımcıları
özelliklerin bu toptan kaldırılmasına katılmadı, çünkü bunların hepsi hariç
çoklu kalıtım yeni dile dahil edilmiştir.
Bununla birlikte, bazı durumlarda C# tasarımcılarının takdirine bağlı olarak, C#'ın C# versiyonu
bir C++ özelliği geliştirildi. Örneğin, C# enum türleri daha güvenlidir
C++'ınkilerden daha iyidir, çünkü bunlar hiçbir zaman örtük olarak tamsayılara dönüştürülmezler. Bu
daha güvenli olmalarını sağlar. Struct tipi, önemli ölçüde değiştirildi
gerçekten kullanışlı bir yapı ile sonuçlanırken, C++'da neredeyse hiçbir amaca hizmet etmez.
poz. C#'ın yapıları Bölüm 12'de tartışılmaktadır. C#,
C, C++ ve Java'da kullanılan switch ifadesi. C# anahtarı tartışılıyor
Bölüm 8.
C++ işlev işaretçileri içermesine rağmen, güvenlik eksikliğini paylaşırlar.
C++'ın değişkenlere yönelik işaretçilerinde doğaldır. C# yeni bir tür içerir, delegeler,
alt programlara hem nesne yönelimli hem de tip güvenli yöntem referansları olan
gram. Delegeler, olay işleyicilerini uygulamak, kontrol etmek için kullanılır.
iş parçacıklarının yürütülmesi ve geri aramalar. 19 Geri aramalar Java'da şu şekilde uygulanır:
arayüzler; C++'da yöntem işaretçileri kullanılır.
C#'da metotlar, değişken sayıda parametre alabilirler.
hepsi aynı tip. Bu, dizinin resmi bir parametresi kullanılarak belirtilir.
params ayrılmış Word'den önce yazın .
Hem C++ hem de Java iki farklı yazım sistemi kullanır: biri ilkel ve
biri nesneler için. Bu, kafa karıştırıcı olmasının yanı sıra, sık sık
17. Diğer birçok dil, .NET dili olacak şekilde değiştirildi.
18. Başlangıçta IL, MSIL (Microsoft Intermediate Language) olarak adlandırılıyordu, ancak görünüşe göre birçok
insanlar bu ismin çok uzun olduğunu düşündü.
19. Bir nesne, başka bir nesnenin yöntemini çağırdığında ve bu yöntem ne zaman bildirilmesi gerekiyorsa
görevini tamamladığında, çağrılan yöntem arayanını geri arar. Bu geri arama olarak bilinir.

Sayfa 124
değerleri iki sistem arasında dönüştürmek—örneğin, ilkel bir değer koymak için
nesneleri depolayan bir koleksiyona dönüştürün. C# değerler arasında dönüşüm yapar
iki tipleme sisteminden kısmen örtük boks yoluyla örtülü ve
Bölüm 12'de ayrıntılı olarak tartışılan kutu açma işlemleri. 20
C#'ın diğer özellikleri arasında, desteklenmeyen dikdörtgen diziler vardır.
çoğu programlama dilinde taşınır ve bir foreach ifadesi
diziler ve koleksiyon nesneleri için yineleyici. Benzer bir foreach ifadesi bulundu
Perl, PHP ve Java 5.0'da. Ayrıca C#, bir alternatif olan özellikleri içerir.
genel veri üyelerine özel. Özellikler, get ile veri üyeleri olarak belirtilir.
ve referanslar ve atamalar yapıldığında örtük olarak çağrılan metotları ayarlayın.
ilişkili veri üyelerine yapılır.
C#, 2002'deki ilk sürümünden bu yana sürekli ve hızlı bir şekilde gelişti.
En son sürüm C# 2010'dur. C# 2010, bir dinamik yazma biçimi ekler,
örtük yazma ve anonim türler (bkz. Bölüm 6).
2.19.3 Değerlendirme
C#, genel olarak hem C++ hem de Java üzerinde bir gelişme anlamına geliyordu.
amaçlı programlama dili. Bazılarının da öyle olduğu iddia edilebilirse de,
özellikler geriye doğru bir adımdır, C# açıkça hareket eden bazı yapıları içerir
öncekilerin ötesindedir. Bazı özellikleri kesinlikle profesyoneller tarafından benimsenecektir.
yakın geleceğin gramer dilleri. Bazıları zaten yapıyor.
Aşağıda bir C# programı örneği verilmiştir:
// C# Örnek Program
// Girdi: listlen'in şundan küçük olduğu bir tamsayı, listlen
//
100, ardından listlen-integer değerleri.
// Çıktı: Daha büyük olan girdi değerlerinin sayısı
//
tüm giriş değerlerinin ortalamasından daha büyük.
Sistemi kullanarak ;
genel sınıf Ch2example {
statik boşluk Main() {
int [] iç liste;
int dinle,
tezgah,
toplam = 0,
ortalama,
sonuç = 0;
intList = yeni int [99];
listlen = Int32.Parse(Console.readLine());
if ((listlen > 0) && (listlen < 100)) {
// Girdiyi bir diziye oku ve toplamı hesapla
for (sayaç = 0; sayaç < listlen; sayaç++) {
20. Bu özellik Java 5.0'da Java'ya eklendi.
2.19 Amiral Gemisi .NET Dili: C# 103

sayfa 125
104
Bölüm 2 Başlıca Programlama Dillerinin Evrimi
intList[sayaç] =
Int32.Parse(Console.readLine());
toplam += intList[sayaç];
} //- for sonu (sayaç ...
// Ortalamayı hesapla
ortalama = toplam / dinle;
// > ortalama olan giriş değerlerini sayın
foreach ( int num olarak intList)
if (sayı > ortalama) sonuç++;
// Sonucu yazdır
Console.WriteLine(
"Değer sayısı > ortalama:" + sonuç);
} //- if'nin sonu ((listlen ...
Başka
Console.WriteLine(
"Hata--giriş listesi uzunluğu yasal değil");
} //- yöntemin sonu Main
} //- sınıfın sonu Ch2example
2.20 Hibrit Dilleri İşaretleme/Programlama
İşaretleme/programlama karma dili, bazılarının
öğelerin yüzdesi, kontrol akışı gibi programlama eylemlerini belirleyebilir ve
hesaplama. Aşağıdaki alt bölümler, bu tür iki melez dili tanıtmaktadır,
XSLT ve JSP.
2.20.1 XSLT
eXtensible Markup Language (XML) bir metamarkup dilidir. böyle bir
dil, biçimlendirme dillerini tanımlamak için kullanılır. XML'den türetilen işaretleme alanı
guages, XML belgeleri olarak adlandırılan veri belgelerini tanımlamak için kullanılır.
mentler. XML belgeleri insan tarafından okunabilir olmasına rağmen, işlenirler.
bilgisayarlar tarafından. Bu işlem bazen yalnızca dönüşümlerden oluşur
etkin bir şekilde görüntülenebilen veya yazdırılabilen formlara. Birçok durumda, bu tür
dönüşümler, bir Web tarayıcısı tarafından görüntülenebilen HTML'ye yapılır. İçinde
diğer durumlarda, belgedeki veriler, diğer formlarda olduğu gibi işlenir.
veri dosyaları.
XML belgelerinin HTML belgelerine dönüştürülmesi belirtilir
başka bir biçimlendirme dilinde, Genişletilebilir Stil Sayfası Dil Dönüşümleri
(XSLT) ( www.w3.org/TR/XSLT ) . XSLT, programlama benzeri işlemleri belirtebilir.
tion. Bu nedenle, XSLT bir biçimlendirme/programlama karma dilidir. XSLT (önceki değeri)
1990'ların sonlarında World Wide Web Consortium (W3C) tarafından tanımlanmıştır.
XSLT işlemcisi, girdi olarak bir XML veri belgesi alan bir programdır.
ment ve bir XSLT belgesi (aynı zamanda bir XML belgesi biçimindedir).
Bu işlemede, XML veri belgesi başka bir XML'e dönüştürülür.

Sayfa 126
belge, 21 XSLT belgesinde açıklanan dönüşümleri kullanarak. bu
XSLT belgesi, şablonları tanımlayarak dönüşümleri belirtir.
XSLT işlemcisi tarafından XML giriş dosyasında bulunabilen veri kalıpları.
XSLT belgesindeki her şablonla ilişkilendirilen dönüşüm,
önce eşleşen verilerin nasıl dönüştürüleceğini belirten talimatlar
çıktı belgesine yerleştiriliyor. Böylece, şablonlar (ve bunlarla ilişkili pro-
kesme) XSLT işlemcisi çalıştırıldığında "yürütülen" alt programlar olarak işlev görür.
XML belgesinin verilerinde bir kalıp eşleşmesi bulur.
XSLT ayrıca daha düşük düzeyde programlama yapılarına sahiptir. Örneğin, bir
XML belgesinin tekrarlanan bölümlerine izin veren döngü yapısı dahil edilmiştir.
seçilecek. Bir de sıralama süreci var. Bu alt düzey yapılar
<for-each> gibi XSLT etiketleriyle belirtilir .
2.20.2 JSP
Java Sunucu Sayfaları Standart Etiket Kitaplığının (JSTL) "çekirdek" kısmı,
biçimi ve amacı olmasına rağmen başka bir biçimlendirme/programlama hibrit dili
pozlar XSLT'ninkilerden farklıdır. JSTL'yi tartışmadan önce,
servlet ve Java Server Pages (JSP) fikirlerini tanıtmak. Bir sunucu uygulaması bir
Bir Web sunucusu sisteminde bulunan ve bu sistemde yürütülen bir Java sınıfının örneği.
Bir sunucu uygulamasının yürütülmesi, görüntülenen bir işaretleme belgesi tarafından istenir
bir Web tarayıcısı tarafından. Sunucu uygulamasının HTML biçimindeki çıktısı
belge, istekte bulunan tarayıcıya döndürülür. İçinde çalışan bir program
Sunucu uygulaması kapsayıcısı olarak adlandırılan web sunucusu işlemi, sunucunun yürütülmesini kontrol eder.
Haydi. Servlet'ler genellikle form işleme ve veritabanı erişimi için kullanılır.
JSP, dinamik Web belgelerini desteklemek için tasarlanmış bir teknolojiler topluluğudur.
Web belgelerinin diğer işleme ihtiyaçlarını karşılar ve sağlar. Ne zaman bir JSP
Genellikle HTML ve Java'nın bir karışımı olan belge, bir
tarayıcı, bir Web sunucusu sisteminde bulunan JSP işlemci programı,
belgeyi bir sunucu uygulamasına dönüştürür. Belgenin gömülü Java kodu
servlete kopyalanır. Düz HTML, Java yazdırma ifadelerine kopyalanır
olduğu gibi çıktı verir. JSP belgesindeki JSTL işaretlemesi şu şekilde işlenir:
aşağıdaki paragrafta tartışılmıştır. JSP işlemi tarafından üretilen sunucu uygulaması-
sor, sunucu uygulaması kapsayıcısı tarafından çalıştırılır.
JSTL, aşağıdakileri kontrol eden bir XML eylem öğeleri koleksiyonu tanımlar.
JSP belgesinin Web sunucusunda işlenmesi. Bu unsurlara sahip
HTML ve XML'in diğer öğeleriyle aynı biçimde. En yaygın olanlardan biri
kullanılan JSTL kontrol eylemi öğeleri, bir Boole ifadesini belirten if şeklindedir.
bir nitelik olarak. 22 if öğesinin içeriği ( açıklık arasındaki metin
etiketi ( <if> ) ve kapanış etiketi ( </if> )) dahil edilecek HTML kodudur
çıktı belgesinde yalnızca Boole ifadesi true olarak değerlendirilirse. bu
eğer öğe C/C++ #if önişlemci komutuyla ilgiliyse . JSP
21. XSLT işlemcisinin çıktı belgesi HTML veya düz metin olarak da olabilir.
2.20 Hibrit Dilleri İşaretleme/Programlama 105
22. Bir öğenin açılış etiketine gömülü olan HTML'deki bir öznitelik, daha fazla bilgi sağlar.
bu eleman hakkında bilgi.

Sayfa 127
106
Bölüm 2 Başlıca Programlama Dillerinin Evrimi
konteyner, JSP belgelerinin JSTL kısımlarını şuna benzer bir şekilde işler.
C/C++ ön işlemcisinin C ve C++ programlarını nasıl işlediği. önişlemci
komutlar, önişlemcinin çıktı dosyasının nasıl olduğunu belirtmesi için talimatlardır.
girdi dosyasından oluşturulacaktır. Benzer şekilde, JSTL kontrol eylem öğeleri
XML çıktısının nasıl oluşturulacağını belirtmek için JSP işlemcisine yönelik talimatlardır.
XML giriş dosyasından dosya.
if öğesinin yaygın bir kullanımı , form verilerinin doğrulanması içindir.
bir tarayıcı kullanıcısı tarafından gönderildi. Form verilerine JSP işlemcisi tarafından erişilebilir ve
mantıklı veri olduğundan emin olmak için if öğesiyle test edilebilir . değilse,
if öğesi, çıktı belgesine kullanıcı için bir hata mesajı ekleyebilir.
Çoklu seçim kontrol için, JSTL vardır seçmek , zaman ve aksi
elementler. JSTL ayrıca toplama üzerinde yinelenen bir forEach öğesi içerir.
tipik olarak bir istemciden gelen form değerleridir. ForEach eleman kutu
dahil başlamak , sonu ve adım onun yinelemeleri kontrol bağlıyor.
ÖZET
geliştirme ve geliştirme ortamlarını araştırdık.
bir dizi programlama dili. Bu bölüm okuyucuya iyi bir
dil tasarımında güncel konulara bakış açısı. için zemin hazırladık.
çağdaş dillerin önemli özelliklerinin derinlemesine tartışılması.
KAYNAKÇA NOTLAR
Gelişmelerle ilgili belki de en önemli tarihsel bilgi kaynağı-
erken programlama dillerinin en önemli özelliği Programlama Dilleri Tarihidir.
Richard Wexelblat (1981) tarafından düzenlendi. Gelişimsel arka planı içerir
ve tasarım tarafından anlatıldığı gibi 13 önemli programlama dilinin ortamı-
kendileri. Benzer bir çalışma, ikinci bir “tarih” konferansından kaynaklandı.
ACM SIGPLAN Notices (ACM, 1993a)' nın özel bir sayısı olarak yayınlandı . Bu işte,
13 programlama dilinin daha tarihi ve evrimi tartışılıyor.
“Programlama Dillerinin Erken Gelişimi” makalesi (Knuth ve
Bilgisayar Bilimi ve Teknolojisi Ansiklopedisi'nin bir parçası olan Pardo, 1977) ,
dillerin gelişimini ayrıntılandıran 85 sayfalık mükemmel bir çalışmadır.
ve Fortran dahil. Kağıt göstermek için örnek programlar içerir
bu dillerin çoğunun özellikleri.
Bir diğer ilgi çeken kitap ise Programlama Dilleri: Tarih ve Eğlence.
temeller, Jean Sammet (1969). ayrıntılarıyla dolu 785 sayfalık bir çalışmadır.
1950'lerin ve 1960'ların 80 programlama dili. Sammet ayrıca pub-
için Programlama Dilleri Listesi gibi kitabında çeşitli güncellemeler yaptı.
1974–75 (1976).

sayfa 128
İNCELEME SORULARI
1. Plankalkül hangi yılda tasarlandı? Bu tasarım hangi yılda
yayınlanan?
2. Plankalkül'e hangi iki ortak veri yapısı dahil edildi?
3. 1950'lerin başlarındaki sözde kodlar nasıl uygulandı?
4. Hız kodlaması, iki önemli eksikliğin üstesinden gelmek için icat edildi.
1950'lerin başındaki bilgisayar donanımı. Onlar neydi?
5. Programların yorumlanmasındaki yavaşlık neden kabul edilebilirdi?
1950'lerin başı?
6. IBM 704 bilgisayarında ilk olarak hangi donanım yeteneği ortaya çıktı?
programlama dillerinin evrimini güçlü bir şekilde etkiledi mi? Sebebini açıkla.
7. Fortran tasarım projesine hangi yılda başlandı?
8. Fortran zamanında bilgisayarların birincil uygulama alanı neydi?
dizayn edildi?
9. Fortran I'in tüm kontrol akışı ifadelerinin kaynağı neydi?
10. Fortran I'e Fortran'ı almak için eklenen en önemli özellik neydi?
II?
11. Fortran'ı elde etmek için Fortran IV'e hangi kontrol akış ifadeleri eklendi?
77?
12. Fortran'ın hangi sürümü, herhangi bir tür dinamiğe sahip olan ilk sürümdü.
değişkenler?
13. Karakter dizisi işlemeye sahip ilk Fortran sürümü hangisidir?
14. 1950'lerin sonlarında dilbilimciler neden yapay zeka ile ilgileniyorlardı?
15. LISP nerede geliştirildi? Kim tarafından?
16. Scheme ve Common LISP ne şekilde birbirinin zıttıdır?
17. Programlamaya giriş dersleri için LISP'in hangi lehçesi kullanılır?
bazı üniversiteler?
18. ALGOL 60'ı hangi iki meslek kuruluşu birlikte tasarladı?
19. ALGOL'ün hangi versiyonunda blok yapısı ortaya çıktı?
20. ALGOL 60'ın hangi eksik dil unsuru, şansını zedeledi.
yaygın kullanım?
21. ALGOL 60'ın sözdizimini tanımlamak için hangi dil tasarlandı?
22. COBOL hangi dile dayalıydı?
23. COBOL tasarım süreci hangi yılda başladı?
24. COBOL'da ortaya çıkan hangi veri yapısı kaynaklandı?
Plankalkül mü?
25. Kuruluşun erken başarısından en çok hangi kuruluş sorumluydu?
COBOL (kullanım kapsamı açısından)?
Soruları gözden geçir 107

Sayfa 129
108
Bölüm 2 Başlıca Programlama Dillerinin Evrimi
26. BASIC'in ilk sürümünün hedefi hangi kullanıcı grubuydu?
27. BASIC neden 1980'lerin başında önemli bir dildi?
28. PL/I hangi iki dilin yerini alacak şekilde tasarlanmıştır?
29. PL/I hangi yeni bilgisayar serisi için tasarlandı?
30. SIMULA 67'nin hangi özellikleri artık bazı nesnelerin önemli parçalarıdır?
odaklı diller?
31. ALGOL 68'de veri yapılandırmasının hangi yeniliği tanıtıldı, ancak
genellikle Pascal'a yatırılır?
32. ALGOL 68'de hangi tasarım kriteri yaygın olarak kullanıldı?
33. Vaka beyanı hangi dille tanıtıldı ?
34. C'deki hangi operatörler ALGOL 68'deki benzer operatörler üzerinde modellenmiştir?
35. C'nin Pascal'dan daha az güvenli olmasını sağlayan iki özelliği nelerdir?
36. Prosedürel olmayan dil nedir?
37. Bir Prolog veritabanını dolduran iki tür ifade nedir?
38. Ada'nın tasarlandığı birincil uygulama alanı nedir?
39. Ada'nın eşzamanlı program birimlerine ne ad verilir?
40. Hangi Ada yapısı soyut veri türleri için destek sağlar?
41. Smalltalk dünyasını ne doldurur?
42. Nesne yönelimli programlamanın temeli hangi üç kavramdır?
43. C++ neden C'nin güvenli olmadığı bilinen özelliklerini içeriyor?
44. Objective-C, yöntem için sözdizimini hangi dilden ödünç alıyor?
aramalar?
45. Neredeyse tüm son zamanlarda tasarlanan dillerin hangi programlama paradigması
destek Go tarafından desteklenmiyor mu?
46. ​​Objective-C için birincil uygulama nedir?
47. Hem C hem de Go üzerinde hangi dil tasarımcısı çalıştı?
48. Ada ve COBOL dillerinin ortak noktası nedir?
49. Java için ilk uygulama neydi?
50. Java'nın hangi özelliği JavaScript'te en belirgindir?
51. PHP ve JavaScript'in yazım sistemi, aşağıdakilerden nasıl farklıdır?
Java?
52. Hangi dizi yapısı C#'da bulunur, ancak C, C++ veya Java'da yoktur?
53. Perl'in orijinal versiyonu hangi iki dilin yerini alacaktı?
54. JavaScript en yaygın olarak hangi uygulama alanı için kullanılmaktadır?
55. JavaScript ve PHP arasındaki ilişki nedir?
kullanmak?
56. PHP'nin birincil veri yapısı, iki veri yapısının birleşimidir.
diğer dillerden türler?

sayfa 130
57. Python, diziler yerine hangi veri yapısını kullanır?
58. Ruby, Smalltalk ile hangi özelliği paylaşıyor?
59. Ruby'nin aritmetik operatörlerinin hangi özelliği onları benzersiz kılar?
diğer diller arasında?
60. Lua'da hangi veri yapıları oluşturulmuştur?
61. Lua normalde derlenir mi, tamamen yorumlanır mı yoksa saf olmayan bir şekilde mi yorumlanır?
62. Delphi sınıflarının hangi özelliği C#'a dahildir?
63. C'nin switch ifadesinin hangi eksikliği aşağıdakilerle giderilir?
C# tarafından bu ifadede yapılan değişiklikler?
64. C#'ın kullanıldığı birincil platform nedir?
65. XSLT işlemcinin girdileri nelerdir?
66. Bir XSLT işlemcinin çıktısı nedir?
67. JSTL'nin hangi öğesi bir alt programla ilgilidir?
68. JSP işlemcisi tarafından dönüştürülen bir JSP belgesi nedir?
69. Sunucu uygulamaları nerede yürütülür?
PROBLEM SETİ
1. Sizce Plankalkül'ün en büyük özellikleri neler olurdu?
Fortran tasarımcıları aşina olsaydı Fortran 0 üzerindeki etkisi
Plankalkül mü?
2. Backus'un 701 Speedcoding sisteminin yeteneklerini belirleyin ve
bunları çağdaş bir programlanabilir elinkilerle karşılaştırın
hesap makinesi.
3. Tarafından tasarlanan A-0, A-1 ve A-2 sistemlerinin kısa bir tarihçesini yazın.
Grace Hopper ve ortakları.
4. Bir araştırma projesi olarak, Fortran 0'ın olanaklarını aşağıdakilerle karşılaştırın.
Laning ve Zierler sistemi.
5. ALGOL tasarım komitesinin üç orijinal hedefinden hangisi,
sence, o zaman başarmak en zoruydu?
6. LISP'deki en yaygın sözdizimi hatasıyla ilgili bilinçli bir tahminde bulunun
programlar.
7. LISP, saf işlevsel bir dil olarak başladı, ancak giderek daha fazla edinildi.
ve daha zorunlu özellikler. Niye ya?
8. Size göre en önemli üç nedeni ayrıntılı olarak açıklayın,
ALGOL 60 neden çok yaygın olarak kullanılan bir dil olmadı?
9. Sizce COBOL neden Fortran'da uzun tanımlayıcılara izin verdi?
ve ALGOL yapmadı mı?
Problem Seti 109

Sayfa 131
110
Bölüm 2 Başlıca Programlama Dillerinin Evrimi
10. IBM'in PL/I geliştirmedeki ana motivasyonunu ana hatlarıyla belirtin.
11. IBM'in PL/I geliştirme kararını temel aldığı varsayımı,
doğru, bilgisayarların tarihi ve o zamandan beri dil gelişmeleri göz önüne alındığında
1964?
12. Programlamada ortogonallik kavramını kendi kelimelerinizle tanımlayın.
ming dili tasarımı.
13. PL/I'nin daha yaygın olarak kullanılmasının başlıca nedeni nedir?
ALGOL 68?
14. Tipsiz düşüncenin hem lehine hem de aleyhine olan argümanlar nelerdir?
dilim?
15. Prolog dışında herhangi bir mantıksal programlama dili var mı?
16. Dillerin çok karmaşık olduğu argümanı hakkında ne düşünüyorsunuz?
plex kullanmak çok tehlikelidir ve bu nedenle tüm dilleri tutmalıyız.
küçük ve basit?
17. Komite tarafından dil tasarımının iyi bir fikir olduğunu düşünüyor musunuz? Destek
senin görüşün.
18. Diller sürekli gelişir. Sizce ne gibi kısıtlamalar
programlama dillerindeki değişiklikler için uygun mu? karşılaştırın
Fortran'ın evrimi ile cevaplar.
19. Tüm önemli dil gelişmelerini tanımlayan bir tablo oluşturun,
ortaya çıktıklarında, ilk hangi dilde ortaya çıktıklarıyla birlikte,
ve geliştiricilerin kimlikleri.
20. Microsoft ve Microsoft arasında bazı genel değiş tokuşlar olmuştur.
Sun, Microsoft'un J++ ve C# ve Sun'ın Java'sının tasarımıyla ilgili.
İlgili sitelerde bulunan bu belgelerden bazılarını okuyun.
Web siteleri ve ilgili anlaşmazlıkların bir analizini yazın
delegeler.
21. Son yıllarda veri yapıları betik dillerinde gelişti
geleneksel dizileri değiştirmek için. Bunların kronolojik sırasını açıklayın
gelişmeler.
22. Saf yorumun neden kabul edilebilir bir uygulama olduğunun iki nedenini açıklayın.
birkaç yeni komut dosyası dili için tation yöntemi.
23. Perl 6 geldiğinde, muhtemelen önemli ölçüde genişletilmiş bir dil olacaktır.
Lua gibi bir dilin de büyüyüp gelişemeyeceği konusunda bilinçli bir tahminde bulunun.
ömrü boyunca sürekli Cevabınızı destekleyin.
24. Sizce neden yeni betik dilleri daha özgür görünüyor?
yeni derlenmiş dillerden daha sık mı?
25. İşaretleme/programlama melezinin kısa bir genel tanımını verin
dilim.

Sayfa 132
PROGRAMLAMAALIŞTIRMALAR
1. Bir programlama dilinde kayıtların değerini anlamak için bir
sağlayan bir dizi yapıyı kullanan, C tabanlı bir dilde küçük bir programdır.
ad, yaş, GPA dahil olmak üzere öğrenci bilgilerini kayan nokta olarak saklayın ve
bir dizi olarak sınıf düzeyi (örneğin, “birinci sınıf” vb.). Ayrıca, aynı pro-
gram yapıları kullanmadan aynı dilde.
2. Bir programlama dilinde özyinelemenin değerini anlamak için bir
önce özyinelemeyi ve ardından hızlı sıralamayı uygulayan program.
özyineleme çıktı.
3. Sayma döngülerinin değerini anlamak için, aşağıdakileri uygulayan bir program yazın:
sayma döngüsü yapılarını kullanarak matris çarpımı. Sonra yaz
aynı program yalnızca mantıksal döngüler kullanır—örneğin, while döngüleri.
Programlama Alıştırmaları 111

Sayfa 133
Bu sayfa bilerek boş bırakılmıştır

Sayfa 134
113
3.1 Giriş
3.2 Sözdizimi Tanımlamanın Genel Sorunu
3.3 Sözdizimi Tanımlamanın Resmi Yöntemleri
3.4 Nitelik Dilbilgileri
3.5 Programların Anlamlarını Tanımlamak: Dinamik Semantik
3
Sözdizimini Tanımlama
ve anlambilim

Sayfa 135
114
Bölüm 3 Sözdizimi ve Semantiği Tanımlama
Bu bölüm aşağıdaki konuları kapsamaktadır. İlk olarak, sözdizimi ve seman- terimleri
tikler tanımlanır. Ardından, en yaygın yöntemin ayrıntılı bir tartışması
sözdizimini tanımlayan, bağlamdan bağımsız gramerler (Backus-Naur Formu olarak da bilinir),
sunuldu. Bu tartışmaya türetmeler, ayrıştırma ağaçları, belirsizlik,
operatör önceliği ve ilişkilendirilebilirlik açıklamaları ve genişletilmiş Backus-Naur
Form. Hem sözdizimini hem de durağanlığı tanımlamak için kullanılabilen nitelik gramerleri
programlama dillerinin semantiği daha sonra tartışılacaktır. Son bölümde üç
anlambilimi tanımlamanın biçimsel yöntemleri—işlemsel, aksiyomatik ve düz anlamsal
semantik - tanıtıldı. Anlambilimin doğasında bulunan karmaşıklık nedeniyle
açıklama yöntemleri, bunlarla ilgili tartışmamız kısa. Biri kolayca yazabilir
kitabın tamamı (birkaç yazarın sahip olduğu gibi) üçünden sadece birinde.
3.1 Giriş
Bir programın kısa ama anlaşılır bir tanımını sağlama görevi-
ming dili zordur ama dilin başarısı için gereklidir. ALGOL 60
ve ALGOL 68 ilk olarak kısa ve öz biçimsel açıklamalar kullanılarak sunuldu; hem de
bununla birlikte, açıklamalar kısmen kolay anlaşılır değildi, çünkü kısmen
her biri yeni bir notasyon kullandı. Her iki dilin de kabul edilme seviyeleri zarar gördü
sonuç olarak. Öte yandan, bazı diller sorundan muzdarip olmuştur.
çok az farklı lehçelere sahip olmak, basit ama gayri resmi ve
kesin olmayan tanım.
Bir dili betimlemedeki sorunlardan biri de insanların çeşitliliğidir.
açıklamayı anlaması gereken ple. Bunlar arasında ilk değerlendiriciler,
uygulayıcılar ve kullanıcılar. Çoğu yeni programlama dili, bir
potansiyel kullanıcılar tarafından, genellikle kuruluş içindeki kişiler tarafından inceleme süresi
Tasarımları tamamlanmadan önce dilin tasarımcısını kullanır. Bunlar
ilk değerlendiriciler Bu geri bildirim döngüsünün başarısı büyük ölçüde şunlara bağlıdır:
açıklamanın netliği.
Programlama dili uygulayıcıları açıkça caydırabilmeli-
bir dilin ifadelerinin, ifadelerinin ve program birimlerinin nasıl olduğunu
oluşturuldu ve yürütüldüğünde amaçlanan etkisi. zorluğu
uygulayıcıların işi, kısmen, uygulamanın eksiksizliği ve kesinliği ile belirlenir.
dil açıklaması.
Son olarak, dil kullanıcıları yazılımı nasıl kodlayacaklarını belirleyebilmelidir.
bir dil referans kılavuzuna başvurarak çözümler. Ders kitapları ve kurslar
bu sürece girin, ancak dil kılavuzları genellikle tek yetkili
bir dil hakkında basılı bilgi kaynağı.
Doğal dillerin incelenmesi gibi programlama dillerinin incelenmesi,
sözdizimi ve anlambilim incelemelerine ayrılabilir. Sözdizimi a
programlama dili, ifadelerinin, ifadelerinin ve programının biçimidir.
birimler. Onun semantik bu ifadeler, ifadeleri ve pro anlamı
gram birimleri. Örneğin, bir Java while ifadesinin sözdizimi şu şekildedir:
while (boolean_expr) ifadesi

Sayfa 136
Bu ifade formunun anlamı şudur:
Boole ifadesi doğrudur, gömülü ifade yürütülür. Aksi halde,
while yapısından sonra kontrol devam eder . Sonra kontrol dolaylı olarak döner
işlemi tekrarlamak için Boole ifadesine.
Genellikle tartışma amacıyla ayrılsalar da, sözdizimi ve
anlambilim yakından ilişkilidir. İyi tasarlanmış bir programlama dilinde,
anlambilim doğrudan sözdiziminden gelmelidir; yani, bir devletin görünüşü-
ment, ifadenin neyi başarmak istediğini kuvvetle önermelidir.
Sözdizimini tanımlamak, anlambilimi tanımlamaktan daha kolaydır, çünkü kısmen bir bağıntı vardır.
cise ve evrensel olarak kabul edilen gösterim, sözdizimi açıklaması için kullanılabilir, ancak
hiçbiri anlambilim için henüz geliştirilmemiştir.
3.2 Sözdizimi Tanımlamanın Genel Sorunu
İster doğal (İngilizce gibi) ister yapay (Java gibi) olsun, bir dil bir kümedir.
bazı alfabelerden karakter dizileri. Bir dilin dizeleri denir
cümleler veya ifadeler. Bir dilin sözdizimi kuralları, hangi dizelerin
dilin alfabesindeki karakterlerin sayısı dildedir. İngilizce, için
örneğin, sözdizimini belirtmek için geniş ve karmaşık bir kurallar koleksiyonuna sahiptir.
onun cümleleri. Karşılaştırıldığında, en büyük ve en karmaşık programlama bile
diller sözdizimsel olarak çok basittir.
Sim için programlama dillerinin sözdiziminin resmi açıklamaları
nezaket adına, genellikle en düşük seviyeli sözdiziminin açıklamalarını içermez.
birimler. Bu küçük birimlere sözlük adı verilir . Sözlüklerin açıklaması
genellikle sözdiziminden ayrı olan sözcüksel bir belirtim ile verilmelidir.
dilin açıklaması. Bir programlama dilinin sözlük birimleri şunları içerir:
diğerlerinin yanı sıra sayısal değişmezleri, işleçleri ve özel sözcükleri. biri düşünebilir
programların karakterlerden ziyade sözlük dizileri olarak.
Sözlükler gruplara ayrılır; örneğin, değişkenlerin adları,
Bir programlama dilinde yöntemler, sınıflar vb. adlı bir grup oluşturur.
tanımlayıcılar. Her sözlük grubu bir ad veya simge ile temsil edilir. Yani, bir jeton
bir dilin sözlük birimlerinin bir kategorisidir. Örneğin, bir tanımlayıcı bir belirteçtir
sözcük birimlerine veya sum ve total gibi örneklere sahip olabilir . Bazı durumlarda, bir
belirtecin yalnızca tek bir olası sözlüğü vardır. Örneğin, arit-
metic operatör sembolü + yalnızca bir olası sözlük birimine sahiptir. Aşağıdakileri göz önünde bulundur
Java ifadesi:
indeks = 2 * sayı + 17;
Bu ifadenin sözlük birimleri ve belirteçleri
sözlükler
Jetonlar
dizin
tanımlayıcı
=
eşittir_işareti
2
int_literal
3.2 Sözdizimi Tanımlamanın Genel Sorunu 115

Sayfa 137
116
Bölüm 3 Sözdizimi ve Semantiği Tanımlama
*
multi_op
saymak
tanımlayıcı
+
artı_op
17
int_literal
;
noktalı virgül
Bu bölümdeki örnek dil açıklamaları çok basittir ve çoğu
sözlük açıklamalarını içerir.
3.2.1 Dil Tanıyıcılar
Genel olarak, diller resmi olarak iki farklı şekilde tanımlanabilir: tanıma yoluyla.
ve nesile göre (her ikisi de tek başına pratik olan bir tanım sağlamasa da)
bir programlama dili öğrenmeye veya kullanmaya çalışan kişiler için). Diyelim ki bir
bir karakter alfabesi kullanan L dili. L'yi resmi olarak tanımlamak için
tanıma yöntemi, tanıma adı verilen bir R mekanizması oluşturmamız gerekir.
alfabeden karakter dizilerini okuyabilen bir cihaz. R olurdu
belirli bir giriş dizesinin L'de olup olmadığını belirtin. Gerçekte, R
verilen dizeyi kabul edin veya reddedin. Bu tür cihazlar, yasal ayrımları ayıran filtreler gibidir.
yanlış oluşturulmuş olanlardan cümleler. R ise, herhangi bir dize beslendiğinde
karakterlerin üzerinde, yalnızca L'deyse kabul eder, o zaman R, L'nin bir açıklamasıdır.
en kullanışlı diller, tüm pratik amaçlar için sonsuzdur, bu şöyle görünebilir:
uzun ve etkisiz bir süreç. Ancak tanıma cihazları şu şekilde kullanılmaz:
bir dilin tüm cümlelerini sıralarlar - farklı bir amaçları vardır.
Bir derleyicinin sözdizimi analizi bölümü, söz konusu dil için bir tanıyıcıdır.
derleyici çevirir. Bu rolde, tanıyıcının olası tüm dizeleri test etmesine gerek yoktur.
Her birinin dilde olup olmadığını belirlemek için bazı kümelerden karakter sayısı. Yerine,
sadece verilen programların dilde olup olmadığını belirlemesi gerekir. Etkisinde
daha sonra sözdizimi çözümleyici, verilen programların sözdizimsel olup olmadığını belirler.
doğru. Ayrıştırıcılar olarak da bilinen sözdizimi çözümleyicilerinin yapısı şu bölümde tartışılmaktadır:
Bölüm 4.
3.2.2 Dil Üreticileri
Bir dil üreteci, aşağıdaki cümleleri oluşturmak için kullanılabilecek bir cihazdır.
dil. Jeneratörü, bir düğme üreten bir düğmeye sahip olarak düşünebiliriz.
dilin cümlesi her itildiğinde. Çünkü özel cümle
düğmesine basıldığında bir jeneratör tarafından üretilen, tahmin edilemez, bir
jeneratör, bir dil tanımlayıcısı olarak sınırlı kullanışlılığa sahip bir cihaz gibi görünüyor.
Ancak, insanlar tanıyıcılara göre belirli türde üreteçleri tercih ederler çünkü
onları daha kolay okuyup anlayabilirler. Buna karşılık, sözdizimi denetimi
bir derleyicinin bir kısmı (bir dil tanıyıcı), bir dil tanımlaması kadar kullanışlı değildir.
sadece deneme yanılma modunda kullanılabildiği için bir programcı için. İçin
örneğin, bir com-kullanarak belirli bir ifadenin doğru sözdizimini belirlemek için
piler, programcı yalnızca tahmin edilen bir sürümü gönderebilir ve

Sayfa 138
derleyici bunu kabul eder. Öte yandan, belirlemek çoğu zaman mümkündür.
belirli bir ifadenin sözdiziminin doğru olup olmadığı ile karşılaştırarak
jeneratörün yapısı.
Resmi üretim ve tanınma arasında yakın bir bağlantı vardır.
Aynı dil için cihazlar. Bu, bilimdeki ufuk açıcı keşiflerden biriydi.
bilgisayar bilimi ve şu anda resmi diller hakkında bilinenlerin çoğuna yol açtı.
ve derleyici tasarım teorisi. Jeneratörlerin ilişkisine dönüyoruz ve
Tanıtıcılar sonraki bölümde.
3.3 Sözdizimi Tanımlamanın Resmi Yöntemleri
Bu bölüm, genellikle resmi dil oluşturma mekanizmalarını tartışır.
program sözdizimini tanımlamak için yaygın olarak kullanılan gramerler olarak adlandırılır .
ming dilleri.
3.3.1 Backus-Naur Biçimi ve Bağlamdan Bağımsız Gramerler
1950'lerin ortalarından sonlarına kadar iki adam, Noam Chomsky ve John Backus,
ilgisiz araştırma çabaları, aynı sözdizimi açıklama biçimciliğini geliştirdi,
daha sonra programlama için en yaygın kullanılan yöntem haline gelen
dil sözdizimi.
3.3.1.1 Bağlamdan Bağımsız Dilbilgisi
1950'lerin ortalarında, tanınmış bir dilbilimci olan Chomsky, (diğer şeylerin yanı sıra)
dört sınıfını tanımlayan dört üretici aygıt veya dilbilgisi sınıfı
diller (Chomsky, 1956, 1959). Bu gramer derslerinden ikisi,
bağlamdan bağımsız ve düzenli, sözdizimini tanımlamak için yararlı olduğu ortaya çıktı.
Programlama dilleri. Programlama dillerinin belirteçlerinin biçimleri
düzenli gramerlerle tanımlanabilir. Tüm programlamanın sözdizimi
diller, küçük istisnalar dışında, bağlamdan bağımsız gramerlerle tanımlanabilir.
Chomsky bir dilbilimci olduğu için, birincil ilgi alanı teorik doğaydı.
doğal dillerdendir. O zamanlar yapay dillere ilgi duymuyordu.
bilgisayarlarla iletişim kurmak için kullanılır. Yani daha sonra onun işi değildi
programlama dillerine uygulanmıştır.
3.3.1.2 Backus-Naur Formunun Kökenleri
Chomsky'nin dil sınıfları üzerindeki çalışmasından kısa bir süre sonra, ACM-GAMM grubu
ALGOL 58'i tasarlamaya başladı.
ACM-GAMM grubunun önde gelen üyelerinden John Backus tarafından sunulan,
1959'da uluslararası bir konferansta (Backus, 1959). Bu kağıt tanıtıldı
programlama dili sözdizimini belirtmek için yeni bir resmi gösterim. bu
yeni gösterim daha sonra Peter Naur tarafından açıklaması için biraz değiştirildi.
3.3 Sözdizimi Tanımlamanın Resmi Yöntemleri 117

Sayfa 139
118
Bölüm 3 Sözdizimi ve Semantiği Tanımlama
ALGOL 60 (Naur, 1960). Bu revize edilmiş sözdizimi açıklama yöntemi,
Backus-Naur Formu veya kısaca BNF olarak bilinir .
BNF, sözdizimini tanımlamak için doğal bir gösterimdir. Aslında buna benzer bir şey
to BNF, Panini tarafından Sanskritçe birkaç yüz sözdizimini tanımlamak için kullanıldı.
İsa'dan yıllar önce (Ingerman, 1967).
ALGOL 60 raporunda BNF kullanımı hemen olmasa da
bilgisayar kullanıcıları tarafından kabul edildi, kısa sürede en popüler hale geldi ve hala
programlama dili sözdizimini kısaca tanımlama yöntemi.
BNF'nin Chomsky'nin üretkenliği ile neredeyse aynı olması dikkat çekicidir.
bağlamdan bağımsız diller için, bağlamdan bağımsız dilbilgisi adı verilen cihazlar . İçinde
Bölümün geri kalanında bağlamdan bağımsız gramerlere basitçe gramer olarak atıfta bulunuyoruz.
Mars. Ayrıca, BNF ve gramer terimleri birbirinin yerine kullanılır.
3.3.1.3 Temeller
Bir üst dildir başka bir dili tanımlamak için kullanılan bir dildir. BNF
programlama dilleri için bir meta dildir.
BNF, sözdizimsel yapılar için soyutlamalar kullanır. Basit bir Java ataması
örneğin ifade, <atama> soyutlaması ile temsil edilebilir.
(sivri parantezler genellikle soyutlamaların adlarını sınırlamak için kullanılır). Gerçek
<atama> tanımı şu şekilde verilebilir:
<atama> → <var> = <ifade>
Uygun bir şekilde adlandırılır okun sol tarafında, metin sol taraf
(LHS), tanımlanan soyutlamadır. Okun sağındaki metin
LHS'nin tanımı. Bu denir sağ taraftaki (ST) ve kon-
belirteçlerin, sözlük birimlerinin ve diğer soyutlamalara yapılan referansların bir karışımından oluşur.
(Aslında belirteçler de soyutlamalardır.) Toplamda, tanım olarak adlandırılır.
kural veya üretim . Az önce verilen örnek kuralda, <var> soyutlamaları
ve <atama> tanımının olması için açıkça tanımlanmış olması gerekir.
kullanışlı.
Bu özel kural, <atama> soyutlamasının şu şekilde tanımlandığını belirtir.
<var> soyutlamasının bir örneği, ardından lexeme = ve ardından bir
<ifade> soyutlama örneği. Sözdizimi olan bir örnek cümle
yapı kural tarafından tanımlanır
toplam = ara toplam1 + ara toplam2
Bir BNF tanımındaki veya dilbilgisindeki soyutlamalara genellikle noninter-
temel semboller veya basitçe terminal olmayanlar ve
kurallara uçbirim sembolleri veya basitçe uçbirimler denir . BNF açıklaması,
veya dilbilgisi , bir kurallar topluluğudur.
Terminal olmayan sembollerin iki veya daha fazla farklı tanımı olabilir;
dilde iki veya daha fazla olası sözdizimsel biçim. Birden çok tanım
ile ayrılmış farklı tanımlarla tek bir kural olarak yazılabilir.

Sayfa 140
sembol | , mantıksal VEYA anlamına gelir. Örneğin, bir Java if ifadesi
kurallarla açıklanan
<if_stmt> → if ( <logic_expr> ) < stmt >
<if_stmt> → if ( <logic_expr> ) < stmt > else <stmt>
veya kural ile
<if_stmt> → if ( <logic_expr> ) < stmt >
| if ( <logic_expr> ) <stmt > else <stmt>
Bu kurallarda, <stmt> ya tek bir ifadeyi ya da bir bileşik ifadeyi temsil eder.
Beyan.
BNF basit olmasına rağmen, hemen hemen hepsini tanımlamak için yeterince güçlüdür.
programlama dillerinin sözdizimi. Özellikle, aşağıdaki listeleri tanımlayabilir:
benzer yapılar, farklı yapıların görünme sırası ve
herhangi bir derinliğe yuvalanmış yapılar ve hatta operatör önceliği ve operasyon anlamına gelir.
tor ilişkilendirme.
3.3.1.4 Listeleri Tanımlama
Matematikte değişken uzunluklu listeler genellikle üç nokta (. . .) kullanılarak yazılır;
1, 2, . . . bir örnektir. BNF üç noktayı içermez, bu nedenle bir alternatif
programlamada sözdizimsel öğelerin listelerini açıklamak için yöntem gereklidir
diller (örneğin, bir veri bildiriminde görünen tanımlayıcıların bir listesi)
Beyan). BNF için alternatif özyinelemedir. Bir kural özyinelemeli ise
LHS, RHS'sinde görünür. Aşağıdaki kurallar özyinelemenin nasıl kullanıldığını gösterir
listeleri açıklamak için:
<ident_list> → tanımlayıcı
| tanımlayıcı, <ident_list>
Bu, <ident_list> öğesini tek bir belirteç (tanımlayıcı) veya bir tanımlayıcı olarak tanımlar.
ardından bir virgül ve başka bir <ident_list> örneği gelir. Özyineleme için kullanılır
Bu bölümün geri kalanında birçok örnek gramerdeki listeleri açıklayın.
3.3.1.5 Dilbilgisi ve Türevler
Dilbilgisi, dilleri tanımlamak için üretken bir aygıttır. cümleleri
dil, kuralların bir dizi uygulamasıyla üretilir,
başlangıç simgesi olarak adlandırılan dilbilgisinin özel bir non-terminal ile başlayan
bol . Bu kural uygulamaları dizisine türetme denir . bir gramerde
eksiksiz bir programlama dili için, başlangıç ​​sembolü bir iletişimi temsil eder.
plete programdır ve genellikle <program> olarak adlandırılır. Gösterilen basit dilbilgisi
Örnek 3.1, türevleri göstermek için kullanılır.
3.3 Sözdizimi Tanımlamanın Resmi Yöntemleri 119

Sayfa 141
120
Bölüm 3 Sözdizimi ve Semantiği Tanımlama
ÖRNEK 3.1
Küçük Bir Dil İçin Bir Dilbilgisi
<Program> → başlar <stmt_list> sonu
<stmt_list> → <stmt>
| <stmt> ; <stmt_list>
<stmt> → <var> = <ifade>
<var> → A | B | C
<ifade> → <var> + <var>
| <var><var>
| <var>
Örnek 3.1'deki dilbilgisi tarafından açıklanan dilin yalnızca bir durumu vardır:
ment formu: atama. Bir program özel sözcük oluşur başlayacak , fol-
noktalı virgülle ayrılmış ifadelerin bir listesi, ardından özel
kelime sonu . Bir ifade ya tek bir değişkendir ya da iki değişken ayrılmıştır
bir ya ile + veya - operatör. Bu dildeki tek değişken isimleri A ,
B ve C .
Bu dilde bir programın bir türevi aşağıdaki gibidir:
<Program> => başlaması <stmt_list> sonu
=> <stmt> başla ; <stmt_list> sonu
=> start <var> = <expression> ; <stmt_list> sonu
=> başla A = <ifade> ; <stmt_list> sonu
=> başla A = <var> + <var> ; <stmt_list> sonu
=> başla A = B + <var> ; <stmt_list> sonu
=> başla A = B + C ; <stmt_list> sonu
=> başla A = B + C ; <stmt> bitiş
=> başla A = B + C ; <var> = <ifade> bitiş
=> başla A = B + C ; B = <ifade> sonu
=> başla A = B + C ; B = <var> sonu
=> başla A = B + C ; B = C sonu
Bu türetme, tüm türetmeler gibi, başlangıç ​​sembolü ile başlar, bu durumda
<program>. => sembolü “türetilir” olarak okunur. Dizideki her ardışık dize
dizi, noninter-
bu terminal olmayanın tanımlarından birine sahip terminaller. Dizilerdeki her bir
<program> dahil olmak üzere türetmeye cümlesel form denir .
Bu türetmede, değiştirilen terminal olmayan her zaman en soldaki non-terminaldir.
önceki cümle biçiminde terminal. Bu sırayı kullanan türevler
değiştirme, en soldaki türevler olarak adlandırılır . türetme şu ana kadar devam eder:
cümlesel formda terminal olmayanlar yoktur. Bu cümle formu, oluşan
yalnızca terminallerin veya sözlük birimlerinin oluşturduğu cümledir.

Sayfa 142
3.3 Sözdizimi Tanımlamanın Resmi Yöntemleri 121
En soldakine ek olarak, bir türetme en sağda veya şu şekilde olabilir:
ne en solda ne en sağda. Türetme sırasının dil üzerinde hiçbir etkisi yoktur.
bir gramer tarafından oluşturulur.
Terminal olmayanları değiştirmek için alternatif RHS kuralları seçerek
türetmede dilde farklı cümleler oluşturulabilir. İle
tüm seçenek kombinasyonlarını kapsamlı bir şekilde seçerek, tüm dil
oluşturuldu. Bu dil, diğerleri gibi, sonsuzdur, bu yüzden kimse üretemez.
dildeki tüm cümleler sonlu bir zamanda.
Örnek 3.2, tipik bir programın parçası için bir gramer örneğidir.
ming dili.
ÖRNEK 3.2
Basit Atama İfadeleri için Bir Dilbilgisi
<atama> → <id> = <ifade>
<id> → A | B | C
<ifade> → <id> + <ifade>
| <id> * <ifade>
| ( <ifade> )
| <id>
Örnek 3.2'nin dilbilgisi, hakkı olan atama ifadelerini açıklar.
taraflar, çarpma ve toplama operatörleri olan aritmetik ifadelerdir ve
parantez. Örneğin, açıklamada
A = B * ( A + C )
en soldaki türetme tarafından oluşturulur:
<atama> => <id> = <ifade>
=> A = <ifade>
=> A = < id > * <ifade>
=> A = B * <ifade>
=> A = B * ( <ifade> )
=> A = B * ( <id> + <ifade> )
=> A = B * ( A + <ifade> )
=> A = B * ( A + <id> )
=> A = B * ( A + C )
3.3.1.6 Ayrıştırma Ağaçları
Gramerlerin en çekici özelliklerinden biri, doğal olarak tanımlamalarıdır.
tanımladıkları dillerin tümcelerinin hiyerarşik sözdizimsel yapısı.
Bu hiyerarşik yapılara ayrıştırma ağaçları denir . Örneğin, ayrıştırma ağacı
Şekil 3.1'de daha önce türetilen atama ifadesinin yapısı gösterilmektedir.

Sayfa 143
122
Bölüm 3 Sözdizimi ve Semantiği Tanımlama
Şekil 3.1
için bir ayrıştırma ağacı
basit ifade
A = B * (A + C)
<atamak>
<id>
A
A
=
<ifade>
<id>
B
*
<ifade>
<id>
<id>
C
+
<ifade>
<ifade>
(
)
Bir ayrıştırma ağacının her dahili düğümü, terminal olmayan bir sembolle etiketlenir.
bol; her yaprak bir terminal sembolü ile etiketlenmiştir. Bir ayrıştırma ağacının her alt ağacı
cümledeki bir soyutlama örneğini tanımlar.
3.3.1.7 Belirsizlik
İki veya daha fazla olan bir cümle biçimi oluşturan bir dilbilgisi
belirgin ayrıştırma ağaçlarının belirsiz olduğu söylenir . Gösterilen dilbilgisini göz önünde bulundurun
Örnek 3.2'de gösterilen dilbilgisinin küçük bir varyasyonu olan Örnek 3.3.
ÖRNEK 3.3
Basit Atama İfadeleri İçin Belirsiz Bir Dilbilgisi
<atama> → <id> = <ifade>
<id> → A | B | C
<ifade> → <ifade> + <ifade>
| <ifade> * <ifade>
| ( <ifade> )
| <id>
Örnek 3.3'ün dilbilgisi belirsiz çünkü cümle
A = B + C * A
Şekil 3.2'de gösterildiği gibi iki ayrı ayrıştırma ağacına sahiptir. Belirsizlik oluşur çünkü
dilbilgisi, dilbilgisine göre biraz daha az sözdizimsel yapı belirtir.

Sayfa 144
3.3 Sözdizimini Tanımlamanın Resmi Yöntemleri 123
Örnek 3.2. Bir ifadenin ayrıştırma ağacının yalnızca büyümesine izin vermek yerine
sağda, bu dilbilgisi hem solda hem de sağda büyümeye izin verir.
Şekil 3.2
İki ayrı ayrıştırma ağacı
aynı cümle için
A = B + C * A
<atamak>
<id>
A
C
B
=
<ifade>
<ifade>
<id>
+
<ifade>
<id>
A
<id>
*
<ifade>
<ifade>
<atamak>
<id>
A
B
=
<ifade>
<ifade>
*
<ifade>
<id>
C
<id>
A
<id>
+
<ifade>
<ifade>
Dil yapılarının sözdizimsel belirsizliği bir sorundur çünkü derleyiciler
genellikle bu yapıların semantiğini sözdizimsel biçimlerine dayandırır. özellikle,
derleyici, bir ifade için oluşturulacak kodu, içeriğini inceleyerek seçer.
ayrıştırma ağacı. Bir dil yapısında birden fazla ayrıştırma ağacı varsa, o zaman ortalama
yapının ne olduğu tek başına belirlenemez. Bu sorun tartışılıyor
Aşağıdaki alt bölümlerde iki özel örnekte.
Bazen bir dilbilgisinin başka özellikleri de vardır.
bir dilbilgisinin belirsiz olup olmadığını belirlemede yararlıdır. 1 Bunlar aşağıdakileri içerir:
alçalma: (1) dilbilgisi en solda birden fazla cümle oluşturuyorsa
türetme ve (2) dilbilgisi birden fazla cümle oluşturuyorsa
en sağdaki türetme.
Bazı ayrıştırma algoritmaları belirsiz gramerlere dayalı olabilir. Ne zaman
böyle bir ayrıştırıcı belirsiz bir yapıyla karşılaşırsa, dilbilgisel olmayan bilgileri kullanır.
doğru ayrıştırma ağacını oluşturmak için tasarımcı tarafından sağlanan mation. birçoğunda
durumlarda, belirsiz bir dilbilgisi, belirsiz olmayacak şekilde yeniden yazılabilir, ancak yine de
İstenen dili oluşturun.
3.3.1.8 Operatör Önceliği
Bir ifade iki farklı operatör içerdiğinde, örneğin, x + y * z ,
bariz bir anlamsal sorun, iki operatörün değerlendirme sırasıdır (için
örneğin, bu ifadede toplama ve çarpma mı yoksa tam tersi mi?). Bu semen-
tic sorusu, operatörlere farklı öncelik seviyeleri atanarak cevaplanabilir.
Örneğin, * 'ye +' dan daha yüksek bir öncelik atanmışsa (dil tarafından
1. Keyfi bir dilbilgisinin olup olmadığını belirlemenin matematiksel olarak imkansız olduğunu unutmayın.
belirsiz.

Sayfa 145
124
Bölüm 3 Sözdizimi ve Semantiği Tanımlama
tasarımcı), görünüm sırasına bakılmaksızın ilk önce çarpma yapılacaktır.
ifadedeki iki operatörün
Daha önce belirtildiği gibi, bir dilbilgisi belirli bir sözdizimsel yapıyı tanımlayabilir.
yapının anlamının bu kısmı, ayrıştırma ağacından belirlenebilir.
Özellikle, bir aritmetik ifadede bir operatörün üretildiği gerçeği
ayrıştırma ağacında daha düşük (ve bu nedenle önce değerlendirilmesi gerekir) için kullanılabilir
ağaçta daha yukarıda üretilen bir operatöre göre önceliğe sahip olduğunu gösterir.
Örneğin, Şekil 3.2'deki ilk ayrıştırma ağacında çarpma operatörü şu şekildedir:
ağaçta daha düşük oluşturulmuş, bu da önceliğe sahip olduğunu gösterebilir.
ifadedeki toplama operatörü. Ancak ikinci ayrıştırma ağacı, indi-
tam tersini yapar. Bu nedenle, iki ayrıştırma ağacının gösterdiği görülüyor.
çelişkili öncelik bilgisi.
Örnek 3.2'deki dilbilgisinin belirsiz olmamasına rağmen,
operatörlerinin öncelik sırası olağan değildir. Bu gramerde bir
belirli bir işleçten bağımsız olarak, birden çok işleçle bir cümlenin ağacını ayrıştırma
ilgili operatörler, en düşük ifadede en sağdaki operatöre sahiptir
ayrıştırma ağacındaki noktayı, ağaçtaki diğer operatörler ilerleme sürecindeyken
ifadede sola doğru hareket ettikçe daha da yükselir. Örneğin,
A + B * C ifadesi , * ağaçtaki en düşük değerdir ve bunun yapılması gerektiğini belirtir
ilk. Bununla birlikte, ekspresyon içerisinde A * B + C , + , bunun düşük belirten
önce yapılacak.
Bozduğumuz basit ifadeler için bir gramer yazılabilir.
hem açık hem de tutarlı bir önceliği belirten küfür
+ ve * operatörleri, operatörlerin bir
ifade. Ayrı terminal dışı kullanılarak doğru sıralama belirtilir.
farklı ön işlemlere sahip operatörlerin işlenenlerini temsil eden semboller
cedans. Bu, ek terminal olmayanlar ve bazı yeni kurallar gerektirir. Bunun yerine
+ ve * öğelerinin her iki işleneni için <expr> kullanarak , üç non-
işlenenleri temsil eden terminaller, dilbilgisinin farklı
operatörleri ayrıştırma ağacında farklı düzeylere taşır. <expr> kök sembolü ise
ifadeler için + , <expr> ile ayrıştırma ağacının en üstüne çıkmaya zorlanabilir.
olarak yeni terminal olmayan <term> kullanarak doğrudan yalnızca + operatörleri oluşturun
+ ' nın sağ işleneni . Ardından, * operatörleri oluşturmak için <term> tanımlayabiliriz ,
sol işlenen olarak <term> ve sağ olarak yeni bir terminal olmayan <faktör> kullanarak
işlenen. Şimdi, * ayrıştırma ağacında her zaman daha aşağıda olacaktır, çünkü sadece
her türetmede başlangıç ​​sembolünden +' dan daha uzak . dilbilgisi
Örnek 3.4 böyle bir gramerdir.

Sayfa 146
3.3 Sözdizimi 125 Tanımlamanın Resmi Yöntemleri
Örnek 3.4'teki dilbilgisi, dilbilgisi ile aynı dili oluşturur.
Örnek 3.2 ve 3.3, ancak açık değildir ve olağan önceliği belirtir.
çarpma ve toplama operatörlerinin dence sırası. Aşağıdaki türetme
A = B + C * A cümlesi için Örnek 3.4'teki dilbilgisi kullanılır:
<atama> => <id> = <ifade>
=> A = <ifade>
=> A = <ifade> + <terim>
=> A = <term> + <term>
=> A = <faktör> + <terim>
=> A = <id> + <terim>
=> A = B + <terim>
=> A = B + <terim> * <faktör>
=> A = B + <faktör> * <faktör>
=> A = B + <id> * <faktör>
=> A = B + C * <faktör>
=> A = B + C * <id>
=> A = B + C * A
Bu cümle için Örnek 3.4'ün gramerini kullanan benzersiz ayrıştırma ağacı,
Şekil 3.3'te gösterilmiştir.
Ayrıştırma ağaçları ve türevler arasındaki bağlantı çok yakındır: Ya
kolayca diğerinden inşa edilebilir. Açıkça ifade edilen her türetme
ous dilbilgisi benzersiz bir ayrıştırma ağacına sahiptir, ancak bu ağaç temsil edilebilir
farklı türevlerle. Örneğin, aşağıdaki cümlenin türetilmesi
A = B + C * A , verilen aynı cümlenin türetilmesinden farklıdır
Önceden. Bu en sağdaki bir türevdir, oysa bir önceki en soldakidir.
Ancak bu türevlerin her ikisi de aynı ayrıştırma ağacıyla temsil edilir.
ÖRNEK 3.4
İfadeler için Kesin Bir Dilbilgisi
<atama> → <id> = <ifade>
<id> → A | B | C
<ifade> → <ifade> + <terim>
| <dönem>
<terim> → <terim> * <faktör>
| <faktör>
<faktör> → ( <ifade> )
| <id>

Sayfa 147
126
Bölüm 3 Sözdizimi ve Semantiği Tanımlama
<atama> => <id> = <ifade>
=> <id> = <ifade> + <term>
=> <id> = <ifade> + <terim> * <faktör>
=> <id> = <ifade> + <term> * <id>
=> <id> = <ifade> + <term> * A
=> <id> = <ifade> + <faktör> * A
=> <id> = <ifade> + <id> * A
=> <id> = <ifade> + C * A
=> <id> = <term> + C * A
=> <id> = <faktör> + C * A
=> <id> = <id> + C * A
=> <id> = B + C * A
=> A = B + C * A
Şekil 3.3
Eşsiz ayrıştırma ağacı
için A = B + C * A
açık bir şekilde kullanmak
dilbilgisi
<atamak>
<id>
A
<id>
<faktör>
<id>
C
B
=
<ifade>
<ifade>
<dönem>
+
<dönem>
<faktör>
A
<id>
*
<dönem>
<faktör>
2. Aynı operatörün iki kez geçtiği bir ifadede aynı sorun var; Örneğin,
A / B / C.
3.3.1.9 Operatörlerin İlişkilendirilmesi
Bir ifade aynı önceliğe sahip iki operatör içerdiğinde (
* ve / genellikle vardır)—örneğin, A / B * C —bir anlam kuralı gereklidir
hangisinin öncelikli olması gerektiğini belirtmek için. 2 Bu kurala çağrışım denir.

Sayfa 148
3.3 Sözdizimi 127 Tanımlamanın Resmi Yöntemleri
Öncelik durumunda olduğu gibi, ifadeler için bir dilbilgisi doğru şekilde olabilir.
operatör birliğini ifade eder. Aşağıdaki bir ödev örneğini düşünün
Beyan:
A = B + C + A
Bu cümlenin ayrıştırma ağacı, Örnek 3.4'teki dilbilgisi ile tanımlandığı gibi,
Şekil 3.4'te gösterilmiştir.
Şekil 3.4'ün ayrıştırma ağacı, sol toplama operatörünü aşağıdakinden daha düşük gösterir.
doğru toplama operatörü. Ekleme kastediliyorsa bu doğru sıralamadır.
tipik olan ilişkisel bırakılmak. Çoğu durumda, ilişkisellik
Bilgisayarda eklenmesi önemsizdir. Matematikte, toplama ilişkiseldir.
tive, yani sol ve sağ ilişkisel değerlendirme sıralarının anlamı
aynı şey. Yani, (A + B) + C = A + (B + C) . Kayan nokta
Bununla birlikte, bir bilgisayarda ekleme, mutlaka çağrışımsal değildir. Örneğin,
kayan noktalı değerlerin yedi basamaklı doğruluk depoladığını varsayalım. Yi hesaba kat
sayılardan birinin 10 7 olduğu 11 sayıyı toplama problemi
ve diğer on tanesi 1'dir. Küçük sayıların (1'lerin) her biri
büyük sayı, birer birer, bu sayı üzerinde hiçbir etkisi yoktur, çünkü
küçük sayılar, büyük sayının sekizinci basamağında bulunur. Ancak,
önce küçük sayılar toplanır ve sonuç
büyük sayı, yedi basamaklı doğrulukta sonuç 1.000001 * 10 7'dir . çıkar-
ister matematikte ister bir matematikte olsun, toplama ve bölme ilişkisel değildir.
bilgisayar. Bu nedenle, bir ifade için doğru ilişkilendirme gerekli olabilir.
bu ikisinden birini içerir.
Şekil 3.4
A = B için bir ayrıştırma ağacı
+ C + A gösteren
ilişkiselliği
ilave
<atamak>
<id>
A
=
<ifade>
<faktör>
<id>
B
<ifade>
<dönem>
+
<ifade>
<dönem>
+
<id>
C
<faktör>
<dönem>
A
<id>
<faktör>

Sayfa 149
128
Bölüm 3 Sözdizimi ve Semantiği Tanımlama
Bir dilbilgisi kuralının LHS'si aynı zamanda onun başlangıcında göründüğünde
RHS, kuralın özyinelemeli bırakıldığı söyleniyor . Bu sol özyineleme solu belirtir
çağrışım. Örneğin, dilbilgisi kurallarının sol özyinelemesi
Örnek 3.4, hem toplama hem de çarpma sol ilişkilendirme yapmasına neden olur.
tive. Ne yazık ki, sol özyineleme bazı önemli sözdizimlerinin kullanımına izin vermez.
analiz algoritmaları. Bu tür algoritmalar kullanılacağı zaman, dilbilgisi
sol özyinelemeyi kaldırmak için değiştirilebilir. Bu da gramere izin vermez.
belirli operatörlerin ilişkisel bırakıldığını kesin olarak belirtmekten. Neyse ki,
sol ilişkilendirme, dilbilgisi olmasına rağmen derleyici tarafından zorlanabilir.
dikte etmez.
Bunu sağlayan çoğu dilde, üs alma operatörü doğru
cıvıl cıvıl. Doğru çağrışımı belirtmek için doğru özyineleme kullanılabilir. Bir gramer kuralı
olduğu doğru özyinelemeli LHS RHS sağ sonunda bulunuyorsa. gibi kurallar
<faktör> → <exp> ** <faktör>
| <exp>
< expr> ( <expr> )
| İD
üs alma işlemini bir sağ ilişkisel operatör olarak tanımlamak için kullanılabilir.
3.3.1.10 if-then-else için Belirsiz Bir Dilbilgisi
Ada if-then-else ifadesi için BNF kuralları aşağıdaki gibidir:
<if_stmt> → eğer <logic_expr> ardından <stmt->
eğer <logic_expr> ardından <stmt-> başka <stmt->
Ayrıca <stmt> → <if_stmt> varsa, bu dilbilgisi belirsizdir. En basit
Bu belirsizliği gösteren cümle biçimi
eğer <logic_expr> sonra eğer <logic_expr> ardından <stmt-> başka <stmt->
Şekil 3.5'teki iki ayrıştırma ağacı, bu cümlesel formun belirsizliğini göstermektedir.
Bu yapının aşağıdaki örneğini düşünün:
eğer yapılan == true
o zaman değer == 0 ise
sonra bölüm = 0;
başka bölüm = sayı / denom;
Sorun şu ki, Şekil 3.5'teki üst ayrıştırma ağacı, bunun için temel olarak kullanılırsa,
çeviri, else yan tümcesi, yapıldığında doğru olmadığında yürütülür , ki bu
muhtemelen yapının yazarı tarafından amaçlanan şey değildir. Yapacağız
Bu else-association problemiyle ilgili pratik problemleri incelemek
Bölüm 8'de.
Biz şimdi bu açıklayan bir kesin dilbilgisi gelişecektir eğer
Beyan. Birçok dilde if yapılarının kuralı, başka bir
fıkra, en yakın önceki eşsiz ile eşleştiğinde mevcut sonra .

Sayfa 150
3.3 Sözdizimi 129 Tanımlamanın Resmi Yöntemleri
Bu nedenle, arasında else olmadan bir if ifadesi olamaz.
o zaman ve onun eşleşmesi else . Dolayısıyla, bu durum için ifadeler farklı olmalıdır.
eşleşenler ve eşleşmeyenler arasında
eşsiz ifadeler başka -daha az ise ler ve diğer tüm ifadeler eşleştirilir.
Önceki dilbilgisi ile ilgili sorun, tüm ifadeleri sanki onlarmış gibi ele almasıdır.
eşit sözdizimsel öneme sahipti - yani hepsi eşleşiyormuş gibi.
Farklı ifade kategorilerini, farklı soyutlamaları veya
terminal olmayanlar kullanılmalıdır. Bu fikirlere dayanan açık dilbilgisi
şöyle:
<stmt> → <eşleşti> | <eşleşmeyen>
<eşleşti> → eğer <logic_expr> ardından <eşleşti> başka <eşleşti>
| if olmayan herhangi bir ifade
<eşsiz> → eğer <logic_expr> ardından <stmt->
| eğer <logic_expr> ardından <eşleşti> başka <eşsiz>
Aşağıdakiler için bu dilbilgisini kullanan tek bir olası ayrıştırma ağacı vardır.
cümle formu:
eğer <logic_expr> sonra eğer <logic_expr> ardından <stmt-> başka <stmt->
Şekil 3.5
İki ayrı ayrıştırma ağacı
aynı cümle için
form
<logic_expr> ise <stmt> yoksa <stmt>
<logic_expr> ise <stmt>
<if_stmt>
<if_stmt>
<logic_expr> ise <stmt> yoksa <stmt>
<if_stmt>
<logic_expr> ise <stmt>
<if_stmt>

Sayfa 151
130
Bölüm 3 Sözdizimi ve Semantiği Tanımlama
3.3.2 Genişletilmiş BNF
BNF'deki birkaç küçük rahatsızlıktan dolayı, BNF'de genişletilmiştir.
birkaç yol. Genişletilmiş sürümlerin çoğu, Genişletilmiş BNF veya yalnızca
EBNF, hepsi tam olarak aynı olmasa da. Uzantıları değil
BNF'nin tanımlayıcı gücünü artırmak; sadece okunabilirliğini arttırırlar ve
yazılabilirlik.
EBNF'nin çeşitli sürümlerinde yaygın olarak üç uzantı bulunur.
Bunlardan ilki, bir RHS'nin isteğe bağlı bir bölümünü belirtir ve bu bölüm şu şekilde sınırlandırılmıştır:
parantez. Örneğin, bir C if-else ifadesi şu şekilde tanımlanabilir:
<if_stmt> → if ( <ifade> ) <ifade> [ başka <ifade> ]
Köşeli parantez kullanılmadan, bu ifadenin sözdizimsel açıklaması
aşağıdaki iki kuralı gerektirir:
<if_stmt> → if ( <ifade> ) <ifade>
| if ( <ifade> ) <ifade> else <ifade>
İkinci uzantı, bir RHS'de parantezlerin kullanılmasıdır.
kapalı kısım süresiz olarak tekrarlanabilir veya tamamen dışarıda bırakılabilir. Bu uzantı-
sion, özyineleme ve iki kural kullanmak yerine listelerin tek bir kuralla oluşturulmasına izin verir.
tüzük. Örneğin, virgülle ayrılmış tanımlayıcı listeleri tanımlanabilir.
aşağıdaki kurala göre:
<ident_list> → <tanımlayıcı> {, <tanımlayıcı> }
Bu, özyinelemenin bir örtülü yineleme biçimiyle değiştirilmesidir; parça
parantez içine alınmış herhangi bir sayıda yinelenebilir.
Üçüncü yaygın uzantı, çoktan seçmeli seçeneklerle ilgilidir. Zaman
bir gruptan tek eleman seçilmelidir, seçenekler parantez içine alınır.
tezler ve VEYA operatörü, | ile ayrılır . Örneğin,
<term> → <terim> ( * | / | % ) <faktör>
BNF'de bu <terim> tanımı aşağıdaki üç kuralı gerektirir:
<terim> → <terim> * <faktör>
| <terim> / <faktör>
| <term> % <faktör>
EBNF uzantılarındaki parantezler, parantezler ve parantezler metasym-
bols , bu, bunların gösterim araçları oldukları ve terminal sembolleri olmadığı anlamına gelir.
tanımlamaya yardımcı oldukları sözdizimsel varlıklar. Bu metasembollerin olduğu durumlarda
ayrıca açıklanan dilde terminal sembolleri, örnekler
terminal sembollerinin altı çizilebilir veya alıntı yapılabilir. Örnek 3.5, kullanımı göstermektedir
EBNF dilbilgisinde parantezler ve çoklu seçenekler.

Sayfa 152
3.3 Sözdizimini Tanımlamanın Resmi Yöntemleri 131
BNF kuralı
<ifade> → <ifade> + <terim>
+ operatörünün ilişkisel bırakılacağını açıkça belirtir -aslında zorlar- . Ancak,
EBNF sürümü,
<ifade> → <term> { + <term>}
ilişkiselliğin yönü anlamına gelmez. Bu sorun aşılır
tasarlayarak ifadeler için bir EBNF dilbilgisine dayalı bir sözdizimi çözümleyicisi
Doğru ilişkilendirmeyi zorlamak için sözdizimi analizi süreci. Bu daha ileri
4. Bölümde tartışılmıştır.
EBNF'nin bazı sürümleri, sayısal bir üst simgenin eklenmesine izin verir.
ekteki parçanın üst sınırını belirtmek için sağ ayraç
tekrar edilebilir. Ayrıca, bazı sürümler birini belirtmek için bir artı ( + ) üst simgesi kullanır.
veya daha fazla tekrar. Örneğin,
<bileşik> → başlar <stmt-> { <stmt-> } end
ve
<bileşik> → başlamak { <stmt-> } + ucunu
eşdeğerdir.
ÖRNEK 3.5
Bir İfade Dilbilgisinin BNF ve EBNF Versiyonları
BNF:
<ifade> → <ifade> + <terim>
| <ifade> - <terim>
| <dönem>
<terim> → <terim> * <faktör>
| <terim> / <faktör>
| <faktör>
<faktör> → <exp> ** <faktör>
<exp>
< expr> ( <expr> )
| İD
EBNF:
<ifade> → <terim> { (+ | -) <terim>}
<terim> → <faktör> { (* | /) <faktör>}
<faktör> → <exp> { ** <exp>}
< expr> ( <expr> )
| İD

Sayfa 153
132
Bölüm 3 Sözdizimi ve Semantiği Tanımlama
Son yıllarda, BNF ve EBNF üzerinde bazı varyasyonlar ortaya çıkmıştır. Arasında
bunlar şunlar:
• Ok yerine iki nokta üst üste işareti kullanılır ve bir sonrakine RHS yerleştirilir
astar.
• Alternatif RHS'leri ayırmak için dikey bir çubuk yerine, bunlar basitçe
ayrı hatlara yerleştirilir.
• Bir şeyin isteğe bağlı olduğunu belirtmek için köşeli parantezler yerine, alt-
komut dosyası seçeneği kullanılır. Örneğin,
Yapıcı Bildirici → SimpleName (FormalParameterList opt )
| parantez içindeki bir öğe listesindeki sembol,
bir seçim yapmak için “biri” kelimeleri kullanılır. Örneğin,
AtamaOperatörü → biri = *= /= %= += -=
<<= >>= &= ^= |=
EBNF için bir standart vardır, ISO/IEC 14977:1996(1996), ancak nadiren
Kullanılmış. Standart, kurallarda ok yerine eşittir işaretini ( = ) kullanır, termi-
her RHS'yi noktalı virgülle yazar ve tüm terminal sembollerinde tırnak işaretleri gerektirir.
Aynı zamanda, bir dizi başka gösterim kurallarını da belirtir.
3.3.3 Dilbilgisi ve Tanıyıcılar
Bu bölümün başlarında, yakın bir ilişki olduğunu öne sürdük.
Belirli bir dil için üretim ve tanıma cihazları arasında Aslında,
bağlamdan bağımsız bir dilbilgisi verildiğinde, tarafından oluşturulan dil için bir tanıyıcı
dilbilgisi algoritmik olarak oluşturulabilir. Bir dizi yazılım sistemi
Bu yapıyı gerçekleştiren temler geliştirilmiştir. Bu tür sistemler
yeni bir derleyicinin sözdizimi analizi bölümünün hızlı bir şekilde oluşturulmasına izin verir.
dildir ve bu nedenle oldukça değerlidir. Bu söz dizimlerinin ilklerinden biri
analizör jeneratörleri yacc 3 olarak adlandırılır (Johnson, 1975). şimdi çok var
gibi sistemler mevcuttur.
3.4 Nitelik Dilbilgileri
Bir Özellik grameri daha fazla A yapısı tarif etmek için kullanılan bir cihazdır
bağlamdan bağımsız bir dilbilgisi ile tanımlanabilecek programlama dilidir. Bir
öznitelik dilbilgisi, bağlamdan bağımsız bir dilbilgisinin bir uzantısıdır. uzantı
3. Yacc terimi, “yine başka bir derleyici derleyicisi”nin kısaltmasıdır.

Sayfa 154
3.4 Nitelik Dilbilgisi 133
belirli dil kurallarının uygun şekilde tanımlanmasına izin verir, örneğin
Tip uyumluluğu olarak. Öznitelik biçimini resmi olarak tanımlamadan önce
ancak gramerler, statik anlambilim kavramını açıklığa kavuşturmalıyız.
3.4.1 Statik Semantik
Programlama yapısının bazı özellikleri vardır.
BNF ile tanımlanması zor olan diller ve bazıları
imkansız. Zor olan sözdizimi kuralına bir örnek olarak
BNF ile belirtin, tür uyumluluk kurallarını göz önünde bulundurun. için Java'da
örneğin, bir ara değere kayan noktalı bir değer atanamaz.
ger tipi değişken, tersi yasal olmasına rağmen. Buna rağmen
kısıtlama BNF'de belirtilebilir, ek olmayan ek gerektirir.
terminal sembolleri ve kuralları. Java'nın tüm yazım kuralları
BNF'de belirtilirse, dilbilgisi olamayacak kadar büyük olur.
kullanışlıdır, çünkü dilbilgisinin boyutu metnin boyutunu belirler.
sözdizimi çözümleyici.
Belirtilemeyen bir sözdizimi kuralı örneği olarak
BNF'de, tüm değişkenlerin olması gereken ortak kuralı göz önünde bulundurun.
referans verilmeden önce bildirilir. Kanıtlanmıştır ki bu
kural BNF'de belirtilemez.
Bu problemler, dil kurallarının kategorilerini örneklemektedir.
statik anlam kuralları denir. Statik semantik bir dilin sadece endike olduğu
yürütme sırasında programların anlamı ile doğrudan ilgili; daha doğrusu yapmak zorunda
programların yasal biçimleriyle (anlambilimden ziyade sözdizimi). Birçok statik
Bir dilin anlamsal kuralları, tür kısıtlamalarını belirtir. Statik anlambilim öyle
Bu özellikleri kontrol etmek için gerekli analizler yapılabildiği için adlandırılmıştır.
derleme zamanında.
BNF ile statik anlambilimin tanımlanmasındaki problemler nedeniyle, çeşitli
bu görev için daha güçlü mekanizmalar geliştirilmiştir. Böyle bir mekan-
Nitelik gramerleri olan nism, Knuth (1968a) tarafından hem
programların sözdizimi ve statik anlambilimi.
Nitelik dilbilgisi, hem tanımlamaya hem de kontrol etmeye yönelik resmi bir yaklaşımdır.
bir programın statik anlambilim kurallarının doğruluğu. olmasalar da
Derleyici tasarımında her zaman resmi bir şekilde kullanılır, özniteliğin temel kavramları
gramerler en azından her derleyicide gayri resmi olarak kullanılır (bkz. Aho ve diğerleri, 1986).
İfadelerin, ifadelerin ve ifadelerin anlamı olan dinamik anlambilim
program birimleri, Bölüm 3.5'te tartışılmaktadır.
3.4.2 Temel Kavramlar
Öznitelik dilbilgisi, öznitelik eklenmiş bağlamdan bağımsız dilbilgisidir.
butes, öznitelik hesaplama işlevleri ve yüklem işlevleri. Nitelikler ,
dilbilgisi sembolleriyle ilişkilendirilen (terminal ve terminal olmayan
semboller), atanmış değerlere sahip olabilmeleri anlamında değişkenlere benzerler.
onlara. Öznitelik hesaplama işlevleri , bazen semantik olarak adlandırılır
tarih notu
Özellik gramerleri
çok çeşitli uygulamalarda kullanılan
katyonlar. alışmışlar
tam açıklamalar sağlayın
sözdizimi ve statik anlam
programlama dilleri tikleri
(Watt, 1979); onlar olmuştur
resmi tanımı olarak kullanılır
girilebilecek bir dil
derleyici oluşturma sistemi
(Farrow, 1982); ve sahipler
birkaçının temeli olarak kullanılmıştır.
sözdizimine yönelik düzenleme sistemleri
(Teitelbaum ve Reps, 1981;
Fischer ve diğerleri, 1984). ek olarak
tion, nitelik gramerlerinin sahip olduğu
doğal dilde kullanılmıştır
işleme sistemleri (Correa,
1992).

Sayfa 155
134
Bölüm 3 Sözdizimi ve Semantiği Tanımlama
işlevler, dilbilgisi kurallarıyla ilişkilidir. Nasıl olduğunu belirtmek için kullanılırlar
öznitelik değerleri hesaplanır. Statik durumu belirten yüklem işlevleri
dilin anlamsal kuralları, dilbilgisi kuralları ile ilişkilidir.
Niteliği resmi olarak tanımladıktan sonra bu kavramlar daha net hale gelecektir.
gramer ve örnek veriniz.
3.4.3 Tanımlanan Nitelik Dilbilgisi
Nitelik dilbilgisi, aşağıdaki ek özelliklere sahip bir dilbilgisidir:
• Her bir dilbilgisi simgesi X ile ilişkilendirilen bir dizi A(X) özniteliğidir. bu
A(X) kümesi, sentezlenmiş olarak adlandırılan iki ayrık küme S(X) ve I(X)'den oluşur.
ve sırasıyla kalıtsal nitelikler. Sentezlenen nitelikler kullanılır
kalıtsal nitelikler iken anlamsal bilgileri bir ayrıştırma ağacına iletmek için
semantik bilgiyi bir ağaçtan aşağı iletir.
• Her dilbilgisi kuralıyla ilişkili bir dizi anlamsal işlev ve
özellikleri üzerinde muhtemelen boş bir yüklem işlevleri kümesi
dilbilgisi kuralındaki semboller. X 0 SX 1 c X n kuralı için , sentez-
X 0'ın boyutlandırılmış öznitelikleri , formun anlamsal fonksiyonları ile hesaplanır
S(X 0 ) = f(A(X 1 ), c , A(X n )). Böylece sentezlenmiş bir özniteliğin değeri
bir ayrıştırma ağacı düğümü, yalnızca o üzerindeki özniteliklerin değerlerine bağlıdır.
düğümün alt düğümleri. X j , 1 … jn sembollerinin kalıtsal nitelikleri
(yukarıdaki kuralda), formun anlamsal bir işleviyle hesaplanır
I(X j ) = f(A(X 0 ), c , A(X n )). Böylece, kalıtsal bir özniteliğin değeri
bir ayrıştırma ağacı düğümü, o düğümün çözümlemesinin öznitelik değerlerine bağlıdır.
ent düğümü ve kardeş düğümlerinin düğümleri. Dairesel önlemek için unutmayın-
kalıtsal nitelikler genellikle formun işlevleriyle sınırlıdır.
I(X j ) = f(A(X 0 ), c , A(X( j -1 ))). Bu form, kalıtsal bir özelliği önler.
ancak ayrıştırma ağacında kendisine veya sağdaki niteliklere bağlı olarak.
• Bir yüklem işlevi,
öznitelik kümesi {A(X 0 ), c , A(X n )} ve bir dizi değişmez öznitelik değeri. Tek
bir nitelik dilbilgisi ile izin verilen türevler, her
her terminal olmayanla ilişkili cate doğrudur. Yanlış yüklem işlev değeri
dilin sözdizimi veya statik anlambilim kurallarının ihlal edildiğini gösterir.
Bir öznitelik dilbilgisinin ayrıştırma ağacı, temeline dayanan ayrıştırma ağacıdır.
BNF dilbilgisi, her birine muhtemelen boş bir dizi öznitelik değeri eklenmiş olarak
düğüm. Bir ayrıştırma ağacındaki tüm öznitelik değerleri hesaplanmışsa, ağaç
tamamen atfedildiğini söyledi . Pratikte her zaman bu şekilde yapılmasa da,
öznitelik değerlerinin tamamlandıktan sonra hesaplandığını düşünmek uygundur.
ilişkilendirilmemiş ayrıştırma ağacı derleyici tarafından oluşturulmuştur.
3.4.4 İçsel Nitelikler
İç öznitelikler , değerleri caydırıcı olan yaprak düğümlerin sentezlenmiş öznitelikleridir.
ayrıştırma ağacının dışında mayınlı. Örneğin, bir değişkenin bir örneğinin türü
program, değişken isimlerini saklamak için kullanılan sembol tablosundan gelebilir.

Sayfa 156
3.4 Nitelik Dilbilgisi 135
ve türleri. Sembol tablosunun içeriği daha önceki beyanlara göre ayarlanır.
ifadeler. Başlangıçta, ilişkilendirilmemiş bir ayrıştırma ağacının yönlendirildiğini varsayarsak.
yapılandırılmış ve öznitelik değerlerine ihtiyaç duyulduğunda, değerlere sahip öznitelikler yalnızca
yaprak düğümlerinin içsel nitelikleri. Bir ayrıştırmada içsel öznitelik değerleri verildiğinde
ağaç, semantik fonksiyonlar kalan öznitelik değerlerini hesaplamak için kullanılabilir.
3.4.5 Nitelik Dilbilgisi Örnekleri
Öznitelik dilbilgilerinin tanımlamak için nasıl kullanılabileceğine dair çok basit bir örnek olarak
statik anlambilim, bir öznitelik dilbilgisinin aşağıdaki parçasını düşünün
Bu , bir Ada prosedürünün sonundaki ismin uyması gereken kuralı açıklar.
prosedürün adıyla eşleştirin. (Bu kural BNF'de belirtilemez.) Dize
<proc_name>.string ile gösterilen <proc_name> özniteliği, gerçek
ayrılmış karakterin hemen ardından bulunan karakter dizisi
derleyici tarafından word prosedürü . Birden fazla olduğunda dikkat edin
bir öznitelik dilbilgisinde bir sözdizimi kuralında bir terminal olmayanın ortaya çıkması,
terminal olmayanlar, onları ayırt etmek için parantez içinde gösterilir. ne de
alt simgeler veya parantezler açıklanan dilin bir parçasıdır.
Sözdizimi kuralı: <proc_def> → prosedür <proc_name> [ 1 ]
<proc_body> bitiş <proc_name> [ 2 ];
Yüklem: <proc_name> [ 1 ] string == <proc_name> [ 2 ] .string
Bu örnekte, yüklem kuralı, öğenin ad dizgisi özniteliğinin
Alt program başlığındaki <proc_name> terminal dışı ad dizesiyle eşleşmelidir
alt programın sonunu izleyen <proc_name> terminal olmayanın özniteliği.
Daha sonra, nitelik dilbilgisinin daha büyük bir örneğini ele alacağız. Bu durumda,
örnek, tür kurallarını kontrol etmek için bir öznitelik dilbilgisinin nasıl kullanılabileceğini gösterir.
basit bir atama ifadesinin Bu atamanın sözdizimi ve statik semantiği
ment ifadesi aşağıdaki gibidir: Değişken isimleri sadece A , B ve C'dir . bu
atamaların sağ tarafı bir değişken veya formdaki bir ifade olabilir
Bir değişkenin başka bir değişkene eklenmesi. Değişkenler iki türden biri olabilir:
int veya gerçek. Bir atamanın sağ tarafında iki değişken olduğunda,
aynı tip olmaları gerekmez. İşlenen olduğunda ifadenin türü
tipler aynı değildir her zaman gerçektir. Aynı olduklarında, ifade
type, işlenenlerin tipidir. Ödevin sol tarafının türü
sağ taraftaki türü eşleştirin. Böylece sağ taraftaki işlenen türleri şunlar olabilir:
karışık, ancak atama yalnızca hedef ve bundan kaynaklanan değer varsa geçerlidir.
Sağ tarafta değerlendiren aynı tipe sahiptir. öznitelik dilbilgisi belirtir
bu statik anlamsal kurallar.
Örnek öznitelik dilbilgisinin sözdizimi kısmı
<atama> → <var> = <ifade>
<ifade> → <var> + <var>
| <var>
<var> → A | B | C

Sayfa 157
136
Bölüm 3 Sözdizimi ve Semantiği Tanımlama
Örnek öznitelik dilbilgisindeki terminal olmayanlar için öznitelikler şunlardır:
aşağıdaki paragraflarda açıklanmıştır:
aktüel_tip —<var> terminal olmayanlarla ilişkili sentezlenmiş bir öznitelik
ve <ifade>. Bir değişkenin gerçek türünü, int veya real'i saklamak için kullanılır veya
ifade. Bir değişken durumunda, gerçek tür içseldir. durumda
bir ifadenin, alt düğümün gerçek türlerinden belirlenir
veya <expr> terminal olmayanın alt düğümleri.
beklenen_türü— Uçbirim dışı ile ilişkilendirilmiş devralınan bir öznitelik
<ifade>. için beklenen int veya real tipini saklamak için kullanılır.
ifadenin sol tarafındaki değişkenin türüne göre belirlenir.
atama beyanı.
Tam öznitelik dilbilgisi, Örnek 3.6'da izlenir.
ÖRNEK 3.6
Basit Atama İfadeleri için Nitelik Dilbilgisi
1. Sözdizimi kuralı: <atama> → <var> = <expr>
Anlamsal kural: <expr>.expected_type ← <var>.actual_type
2. Sözdizimi kuralı: <expr> → <var>[2] + <var>[3]
Anlamsal kural: <expr>.actual_type ←
if (<var>[2].actual_type = int) ve
(<var>[3].actual_type = int)
sonra int
başka gerçek
eğer son
Yüklem: <expr>.actual_type == <expr>.expected_type
3. Sözdizimi kuralı: <expr> → <var>
Anlamsal kural: <expr>.actual_type ← <var>.actual_type
Yüklem: <expr>.actual_type == <expr>.expected_type
4. Sözdizimi kuralı: <var> → A | B | C
Anlamsal kural: <var>.actual_type ← look-up(<var>.string)
Arama işlevi, sembol tablosunda belirli bir değişken adını arar ve
değişkenin türünü döndürür.
A = A + B cümlesinin dilbilgisi tarafından oluşturulan bir ayrıştırma ağacı
Örnek 3.6, Şekil 3.6'da gösterilmiştir. Dilbilgisinde olduğu gibi, parantez içindeki sayılar
ağaçta tekrarlanan düğüm etiketlerinden sonra eklenirler, böylece başvurulabilirler
açık bir şekilde.

Sayfa 158
3.4 Nitelik Dilbilgisi 137
3.4.6 Özellik Değerlerinin Hesaplanması
Şimdi, bir ayrıştırma ağacının öznitelik değerlerini hesaplama sürecini düşünün,
buna bazen ayrıştırma ağacını süslemek denir . Tüm nitelikler olsaydı
devralınırsa, bu tamamen yukarıdan aşağıya bir düzende ilerleyebilir,
yapraklara kök. Alternatif olarak, tamamen dipte ilerleyebilir.
tüm nitelikler sentezlenmişse, yapraklardan köke kadar.
Dilbilgimiz hem sentezlenmiş hem de kalıtsal niteliklere sahip olduğundan,
değerlendirme süreci tek yönlü olamaz. Aşağıdaki bir
özelliklerin hesaplanmasının mümkün olduğu bir sırayla değerlendirilmesi
onlara:
1. <var>.actual_type ← arama( A ) (Kural 4)
2. <expr>.expected_type ← <var>.actual_type (Kural 1)
3. <var>[2].actual_type ← arama( A ) (Kural 4)
<var>[3].actual_type ← arama( B ) (Kural 4)
4. <expr>.actual_type ← int veya real (Kural 2)
5. <expr>.expected_type == <expr>.actual_type
DOĞRU veya YANLIŞ (Kural 2)
Şekil 3.7'deki ağaç, örnekteki öznitelik değerlerinin akışını göstermektedir.
Şekil 3.6. Ayrıştırma ağacı için düz çizgiler kullanılır; kesikli çizgiler özelliği gösterir
ağaçta akış.
Şekil 3.8'deki ağaç, düğümlerdeki nihai öznitelik değerlerini göstermektedir. Bunda
örneğin, A gerçek, B ise int olarak tanımlanır.
Bir özniteliğin genel durumu için öznitelik değerlendirme sırasını belirleme
dilbilgisi, bir bağımlılığın oluşturulmasını gerektiren karmaşık bir problemdir.
tüm öznitelik bağımlılıklarını gösteren grafik.
<atamak>
<var>[3]
B
<var>[2]
A
=
+
<var>
A
<ifade>
Şekil 3.6
için bir ayrıştırma ağacı
A = A + B

Sayfa 159
138
Bölüm 3 Sözdizimi ve Semantiği Tanımlama
beklenen_tip
<atamak>
<var>[3]
B
<var>[2]
A
=
+
<var>
A
<ifade>
gerçek_tip
gerçek_tip
gerçek_tip
gerçek_tip
<atamak>
<var>[3]
B
gerçek_tip =
int_type
gerçek_tip =
real_type
<var>[2]
A
=
+
<var>
A
gerçek_tip =
real_type
<ifade> beklenen_tip = gerçek_tip
gerçek_tip = gerçek_tip
Şekil 3.7
Niteliklerin akışı
ağaçta
Şekil 3.8
Tamamen atfedilen
ayrıştırma ağacı
3.4.7 Değerlendirme
Bir dilin statik anlamsal kurallarını kontrol etmek, tüm iletişimin önemli bir parçasıdır.
kazıklar. Bir derleyici yazar, bir nitelik dilbilgisini hiç duymamış olsa bile,
ya da statik kontrolleri tasarlamak için temel fikirlerini kullanması gerekecekti.
onun derleyicisi için anlambilim kuralları.
Tüm bunları tanımlamak için bir nitelik dilbilgisi kullanmanın ana zorluklarından biri
gerçek bir çağdaş programlama dilinin sözdizimi ve statik semantiği
öznitelik dilbilgisinin boyutu ve karmaşıklığıdır. Çok sayıda attri-
tam bir programlama dili için gerekli olan butes ve semantik kurallar
bu tür gramerlerin yazılması ve okunması zor. Ayrıca, öznitelik değerleri
büyük bir ayrıştırma ağacının değerlendirilmesi maliyetlidir. Öte yandan, daha az resmi nitelik

sayfa 160
3.5 Programların Anlamlarını Tanımlamak: Dinamik Anlambilim 139
gramerler, derleyici yazarlar için güçlü ve yaygın olarak kullanılan bir araçtır.
bir derleyici üretme süreciyle ilgilendiklerinden daha fazla ilgileniyorlar
formalizm.
3.5 Programların Anlamlarını Tanımlamak: Dinamik Semantik
Şimdi dinamik anlambilimi tanımlamanın zor görevine dönüyoruz veya
Bir programlamanın ifadeleri, deyimleri ve program birimlerinin anlamı
dilim. Mevcut gösterimin gücü ve doğallığı nedeniyle,
sözdizimini tanımlamak nispeten basit bir konudur. Öte yandan hiçbir üniversite-
Dinamik anlambilim için sally kabul edilen gösterim veya yaklaşım geliştirilmiştir.
Bu bölümde, geliştirilen yöntemlerden birkaçını kısaca açıklıyoruz.
oped. Bu bölümün geri kalanı için, terimini kullanırken anlambilim, biz
dinamik anlambilim anlamına gelir.
Bir metodoloji ihtiyacının altında yatan birkaç farklı neden vardır.
ve anlambilimi açıklamak için gösterim. Programcıların açıkça bilmesi gerekir
bir dilin ifadelerinin, onları etkili bir şekilde kullanmadan önce tam olarak ne yaptığıdır.
programlarında ısrarla. Derleyici yazarları tam olarak hangi dili bilmelidir
yapılar, onlar için uygulamaları doğru bir şekilde tasarlamak anlamına gelir. eğer bir
bir programlama dilinin kesin semantik belirtimi, yazılan programlar
dilde potansiyel olarak doğru olduğu test edilmeden kanıtlanabilir. Ayrıca, com-
pillerin tam olarak davranışı sergileyen programlar ürettiği gösterilebilir.
dil tanımında verilen; yani, doğrulukları doğrulanabilir. A
bir programlama dilinin sözdizimi ve semantiğinin tam belirtimi
dil için otomatik olarak bir derleyici oluşturmak için bir araç tarafından kullanılabilir.
Son olarak, dilin anlamsal tanımlarını geliştirecek olan dil tasarımcıları,
dilleri, süreç içinde belirsizlikleri ve tutarsızlıkları keşfedebilir
tasarımlarında.
Yazılım geliştiricileri ve derleyici tasarımcıları genellikle
dildeki İngilizce açıklamaları okuyarak programlama dillerinin semantiği
kılavuz kılavuzları. Bu tür açıklamalar genellikle belirsiz ve eksik olduğundan,
bu yaklaşım açıkça tatmin edici değildir. Tam anlambilim eksikliği nedeniyle
programlama dillerinin özellikleri, programların doğruluğu nadiren kanıtlanır
test etmeden ve ticari derleyiciler asla otomatik olarak oluşturulmaz
dil açıklamalarından.
Bölüm 15'te açıklanan işlevsel bir dil olan Scheme, yalnızca
tanımı resmi bir anlambilim içeren birkaç programlama dili
tanım. Bununla birlikte, kullanılan yöntem bu bölümde açıklananlardan biri değildir, çünkü
bu bölüm, zorunlu diller için uygun yaklaşımlara odaklanmaktadır.
3.5.1 İşlemsel Anlambilim
İşlemsel anlambilimin ardındaki fikir, bir kavramın anlamını tanımlamaktır.
bir makinede çalıştırmanın etkilerini belirterek deyim veya program.
Makine üzerindeki etkiler, yapısındaki değişikliklerin sırası olarak görülür.

Sayfa 161
140
Bölüm 3 Sözdizimi ve Semantiği Tanımlama
durum, burada makinenin durumu, deposundaki değerlerin toplamıdır.
Açık bir operasyonel anlambilim açıklaması, daha sonra, bir yürütülerek verilir.
Programın bir bilgisayarda derlenmiş sürümü. Çoğu programcıda,
en az bir vesileyle, anlamını belirlemek için küçük bir test programı yazdı
genellikle dili öğrenirken bazı programlama dili yapısının.
Esasen, böyle bir programcının yaptığı şey, operasyonel semantiği kullanmaktır.
yapının anlamını belirlemek için.
Bu yaklaşımı tam bir formalite için kullanmanın çeşitli sorunları vardır.
semantik açıklamalar. İlk olarak, makinenin yürütülmesindeki bireysel adımlar
dil ve makinenin durumunda meydana gelen değişiklikler çok küçük ve
çok sayıda. İkincisi, gerçek bir bilgisayarın depolama alanı çok büyük ve karmaşıktır.
Genellikle birkaç bellek aygıtı düzeyi ve ayrıca aşağıdakilere bağlantılar vardır:
ağlar aracılığıyla numaralandırılabilir diğer bilgisayarlar ve bellek aygıtları. Orası-
formel işlemler için makine dilleri ve gerçek bilgisayarlar kullanılmaz.
anlambilim. Bunun yerine, idealize edilmiş diller için orta seviye diller ve tercümanlar
bilgisayarlar süreç için özel olarak tasarlanmıştır.
Operasyonel semantiğin farklı kullanım seviyeleri vardır. en yüksekte
düzeyde, ilgi, eksiksiz bir programın yürütülmesinin nihai sonucudur.
Buna bazen doğal işlemsel anlambilim denir . En alt düzeyde,
işlemsel anlambilim, bir programın kesin anlamını belirlemek için kullanılabilir.
gram, durum değişikliklerinin tam dizisinin incelenmesi yoluyla
program çalıştırıldığında oluşur. Bu kullanıma bazen yapısal denir.
operasyonel anlambilim .
3.5.1.1 Temel Süreç
Bir dilin operasyonel semantik tanımını oluşturmanın ilk adımı
birincil karakterin bulunduğu uygun bir ara dil tasarlamaktır.
dilin aktörü netliktir. Ara düzlemin her yapısı
guage açık ve net bir anlama sahip olmalıdır. Bu dil
orta seviye, çünkü makine dili kolayca olamayacak kadar düşük seviyeli
anlaşılmıştır ve başka bir üst düzey dilin uygun olmadığı açıktır. Eğer
semantik açıklaması, sanal bir işlem olan doğal operasyonel semantik için kullanılacaktır.
ara dil için makine (bir tercüman) oluşturulmalıdır.
Sanal makine, tekli ifadelerden herhangi birini yürütmek için kullanılabilir, kod seg-
veya tüm programlar. Anlamsal açıklama, bir
tek bir ifadenin anlamı gerekliyse sanal makine. İçinde
Yapısal işlemsel anlambilim olan bu kullanım, ara kod
görsel olarak kontrol edilmelidir.
İşlemsel anlambilimin temel süreci olağandışı değildir. Aslında, kon-
cept, programlama ders kitaplarında ve programlama dilinde sıklıkla kullanılır
referans kılavuzları. Örneğin, C semantik için yapının olabilir
gibi daha basit ifadelerle tanımlanır.

Sayfa 162
3.5 Programların Anlamlarını Tanımlamak: Dinamik Anlambilim 141
Böyle bir tanımlamanın insan okuyucusu sanal bilgisayardır ve
tanımdaki talimatları doğru bir şekilde “yürütebilmek” ve tanıyabilmek
“yürütme”nin etkileri.
için kullanılan ara dil ve onunla ilişkili sanal makine
resmi işlemsel anlambilim açıklamaları genellikle oldukça soyuttur. Inter-
arabulucu dil, sanal makine için uygun olması anlamına gelir.
insan okuyucular için olduğundan daha fazla. Ancak bizim amaçlarımız için daha insan odaklı bir
ara dil kullanılabilir. Böyle bir örnek olarak, aşağıdakileri göz önünde bulundurun-
anlamlarını açıklamak için yeterli olacak ifadelerin bir listesini
tipik bir programlama dilinin basit kontrol ifadeleri:
özdeş = var
özdeş = özdeş + 1
ident = ident 1
etikete git
if var relop var goto etiketi
Bu ifadelerde relop, kümedeki ilişkisel operatörlerden biridir.
{=, <>, >, <, >=, <=}, ident bir tanımlayıcıdır ve var bir tanımlayıcıdır
veya bir sabit. Bu ifadelerin tümü basittir ve bu nedenle anlaşılması kolaydır
ve uygulamak.
Bu üç atama ifadesinin hafif bir genellemesi daha fazlasını sağlar.
genel aritmetik ifadeler ve tanımlanacak atama ifadeleri. bu
yeni açıklamalar
ident = var bin_op var
ident = un_op var
burada bin_op bir ikili aritmetik işleç ve un_op bir birli işleçtir.
Elbette çoklu aritmetik veri türleri ve otomatik tür dönüşümleri,
Bu genellemeyi çoğaltın. Sadece birkaç tane daha nispeten basit talimat ekleme
dizilerin, kayıtların, işaretçilerin ve alt programların anlambiliminin
tarif edilmiştir.
Bölüm 8'de, çeşitli kontrol ifadelerinin semantiği açıklanmıştır.
bu ara dili kullanarak.
C Bildirimi
Anlam
for (ifade1; ifade2; ifade3) {
. . .
}
ifade1 ;
loop: eğer ifade2 == 0 git dışarı
. . .
ifade3 ;
döngüye git
dışarı: . . .

Sayfa 163
142
Bölüm 3 Sözdizimi ve Semantiği Tanımlama
3.5.1.2 Değerlendirme
Resmi işlemsel anlambilimin ilk ve en önemli kullanımı,
PL/I'nin semantiğini betimler (Wegner, 1972). O özel soyut
makine ve PL/I için çeviri kuralları birlikte Viyana olarak adlandırıldı.
Tanımlama Dili (VDL), IBM'in tasarladığı şehirden sonra.
İşlemsel anlambilim, anlambilimi tanımlamanın etkili bir yolunu sağlar.
açıklamalar olduğu sürece, dil kullanıcıları ve dil uygulayıcıları için
basit ve gayri resmi tutuldu. PL/I'nin VDL açıklaması maalesef öyle
hiçbir pratik amaca hizmet etmemesi karmaşıktır.
İşlemsel anlambilim, daha düşük programlama dillerine bağlıdır.
seviyeler, matematik değil. Bir programlama dilinin ifadeleri
daha düşük seviyeli bir programlama dilinin ifadeleriyle tanımlanır.
Bu yaklaşım, kavramların dolaylı olarak tanımlandığı döngüselliklere yol açabilir.
kendileri açısından. Aşağıdaki iki bölümde açıklanan yöntemler
matematiğe dayalı olmaları anlamında çok daha resmi ve
programlama dilleri değil mantık.
3.5.2 Düz Anlamsal Anlam
Düz anlambilim , en titiz ve en yaygın olarak bilinen biçimsel anlambilimdir.
programların anlamını tanımlama yöntemi. Sağlam bir şekilde özyineleme üzerine kuruludur.
fonksiyon teorisi. Anlamsal anlambilimin kullanımına ilişkin kapsamlı bir tartışma
programlama dillerinin anlambilimini tanımlamanın zorunlu olarak uzun ve
kat. Okuyucuya merkeze bir giriş sağlamak niyetindeyiz.
olan birkaç basit örnekle birlikte düz anlamsal anlambilim kavramları
programlama dili spesifikasyonları ile ilgilidir.
için bir düz anlamsal semantik belirtimi oluşturma süreci
programlama dili, her dil varlığı için hem bir
matematiksel nesne ve bu dil varlığının örneklerini eşleyen bir işlev
matematiksel nesnenin örnekleri üzerine. Çünkü nesneler titizlikle
tanımlı, karşılık gelen varlıklarının tam anlamını modellerler. Fikir
matematiği manipüle etmenin kesin yolları olduğu gerçeğine dayanır.
cal nesneleri, ancak programlama dili yapılarını değil. Bununla zorluk
yöntem, nesnelerin ve eşleme işlevlerinin oluşturulmasında yatmaktadır. yöntem
matematiksel nesneler anlamını ifade ettiği için düz anlamsal olarak adlandırılır .
karşılık gelen sözdizimsel varlıkları.
Bir düz anlamsal semantik programlama dilinin eşleme işlevleri
Spesifikasyon, matematikteki tüm fonksiyonlar gibi, bir etki alanına ve bir aralığa sahiptir. bu
etki alanı, işlev için geçerli parametreler olan değerlerin toplamıdır;
aralık, parametrelerin eşlendiği nesnelerin koleksiyonudur. İçinde
düz anlambilim, etki alanına sözdizimsel etki alanı denir , çünkü
eşlenen sözdizimsel yapılar. Aralığa anlamsal alan adı verilir .
Düz anlambilim, işlemsel anlambilim ile ilgilidir. çalışır durumda
anlambilim, programlama dili yapıları daha basit pro-
anlamın temeli haline gelen dilbilgisi yapıları

Sayfa 164
3.5 Programların Anlamlarını Tanımlamak: Dinamik Semantik 143
inşa etmek. Düz anlambilimde, programlama dili yapıları
kümeler veya daha sık olarak işlevler gibi matematiksel nesnelere eşlenir. Nasıl-
İşlemsel anlambilimden farklı olarak düz anlambilim, hiçbir zaman
programların adım adım hesaplamalı işlenmesi.
3.5.2.1 İki Basit Örnek
Çok basit bir dil yapısı kullanıyoruz, karakter dizisi gösterimleri
İkili sayılar, düz anlam yöntemini tanıtmak. Böyle bir sözdizimi
ikili sayılar aşağıdaki dilbilgisi kurallarıyla tanımlanabilir:
<bin_num> → '0'
|'1'
| <bin_num> '0'
| <bin_num> '1'
Örnek ikili sayı 110 için bir ayrıştırma ağacı Şekil 3.9'da gösterilmektedir. Farkına varmak
matematiksel olmadıklarını göstermek için sözdizimsel rakamların etrafına kesme işareti koyduğumuzu
ematik rakamlar. Bu, ASCII kodlu rakamlar ve
matematiksel rakamlar. Bir program bir sayıyı dizge olarak okuduğunda,
programda bir değer olarak kullanılmadan önce matematiksel bir sayıya çevrilmiştir.
<bin_num>
<bin_num>
'0'
<bin_num>
'1'
'1'
Şekil 3.9
Bir ayrıştırma ağacı
ikili sayı 110
İkili sayılar için eşleme işlevinin sözdizimsel alanı,
ikili sayıların tüm karakter dizisi gösterimleri kümesi. anlamsal
etki alanı, N ile sembolize edilen, negatif olmayan ondalık sayılar kümesidir.
Düz anlambilim kullanarak ikili sayıların anlamını açıklamak,
gerçek anlamı (ondalık sayı) olan her kuralla ilişkilendiririz.
RHS'si olarak tek terminal sembolü.
Örneğimizde, ondalık sayılar ilk iki ile ilişkilendirilmelidir.
dil bilgisi kuralları. Diğer iki dilbilgisi kuralı bir bakıma hesaplamaya dayalıdır.
kurallar, çünkü bir nesnenin bağlanabileceği bir terminal sembolünü birleştirirler.
bazılarını temsil etmesi beklenebilecek bir terminal dışı ile ilişkili
inşa etmek. Ayrıştırma ağacında yukarı doğru ilerleyen bir değerlendirme varsayarsak,

Sayfa 165
144
Bölüm 3 Sözdizimi ve Semantiği Tanımlama
sağ taraftaki terminal olmayanın anlamı zaten eklenmiş olacaktır.
Bu nedenle, RHS'si olarak terminal olmayan bir sözdizimi kuralı, bir işlev gerektirir.
anlamını temsil eden LHS'nin anlamını hesapladı
RHS'yi tamamlayın.
M bin adlı anlamsal işlev, sözdizimsel nesneleri şu şekilde eşler:
önceki dilbilgisi kurallarında açıklanan, N'deki nesnelere, olmayanlar kümesi
negatif ondalık sayılar. M bin işlevi aşağıdaki gibi tanımlanır:
M bin ('0') = 0
M bin ('1') = 1
M bin (<bin_num> '0' ) = 2 * M bin (<bin_num>)
M bin (<bin_num> '1' ) = 2 * M bin (<bin_num>) + 1
Anlamlar veya belirtilen nesneler (bu durumda ondalık sayılardır),
önceki sayfada gösterilen ayrıştırma ağacının düğümlerine eklenebilir,
ağacı Şekil 3.10'da veriyor. Bu, sözdizimine yönelik anlambilimdir. Sözdizimsel
varlıklar, somut anlamı olan matematiksel nesnelere eşlenir.
<bin_num>
<bin_num>
'0'
<bin_num>
'1'
'1'
1
3
6
Şekil 3.10
ile bir ayrıştırma ağacı
110 için belirtilen nesneler
Kısmen daha sonra ihtiyacımız olduğu için, şimdi tarif için benzer bir örnek gösteriyoruz.
sözdizimsel ondalık değişmezlerin anlamını. Bu durumda, sözdizimsel etki alanı
ondalık sayıların karakter dizisi gösterimleri kümesidir. anlamsal
etki alanı bir kez daha N kümesidir.
<dec_num> → '0'|'1'|'2'|'3'|'4'|'5'|'6'|'7''8'|'9'
| <dec_num> ( '0'|'1'|'2'|'3'|'4'|'5'|'6'|'7'|'8'|'9' )
Bu sözdizimi kuralları için düz anlam eşlemeleri:
M dec ( '0' ) = 0, M dec ( '1' ) = 1, M dec ( '2' ) = 2, . . ., M aralık ( '9' ) = 9
M dec (<dec_num> '0' ) = 10 * M dec (<dec_num>)
M dec (<dec_num> '1' ) = 10 * M dec (<dec_num>) + 1
. . .
M dec (<dec_num> '9' ) = 10 * M dec (<dec_num>) + 9

Sayfa 166
3.5 Programların Anlamlarını Tanımlamak: Dinamik Semantik 145
İlerleyen bölümlerde düz anlambilimsel betimlemeleri sunuyoruz.
birkaç basit yapıdan oluşur. En önemli basitleştirici varsayım
Burada yapılan, yapıların hem sözdiziminin hem de statik anlambiliminin
doğru. Ayrıca, yalnızca iki skaler türün dahil edildiğini varsayıyoruz: tamsayı
ve Boole.
3.5.2.2 Bir Programın Durumu
Bir programın düz anlamsal semantiği, durum açısından tanımlanabilir.
ideal bir bilgisayardaki değişiklikler. İşlemsel anlambilim bu şekilde tanımlanır,
ve düz anlambilimsel anlambilim hemen hemen aynı şekilde tanımlanır. daha sonra
sadeleştirme, ancak, düz anlamsal anlambilim yalnızca terimlerle tanımlanır.
programın tüm değişkenlerinin değerleri. Yani, düz anlamsal anlambilim kullanır
anlamı açıklamak için programın durumu, işlemsel anlambilim ise
bir makinenin durumunu kullanır. Operasyonel anlambilim arasındaki temel fark
ve düz anlambilimsel anlambilim, işlemsel anlambilimdeki durum değişikliklerinin
bazı programlama dillerinde yazılmış kodlanmış algoritmalar tarafından tanımlanır, oysa
düz anlambilimde, durum değişiklikleri matematiksel fonksiyonlarla tanımlanır.
Bir programın s durumu, sıralı çiftler kümesi olarak temsil edilsin.
şöyle:
s = { <i 1 , v 1 >, <i 2 , v 2 >, . . . , <i n , v n > }
Her i bir değişkenin adıdır ve ilişkili v'ler geçerli değerlerdir.
bu değişkenlerden. V yılların herhangi bir özel değere sahip olabilir undef , endike olan
ilişkili değişkeninin şu anda tanımsız olduğunu belirtir. VARMAP bir olsun
iki parametrenin işlevi: bir değişken adı ve program durumu. Değer
VARMAP (i j , s) v, J (ı ile eşleştirilmiş değeri j durumu s). Çoğu anlambilim
programlar ve programlar için eşleme işlevleri, durumları durumlara eşler.
Bu durum değişiklikleri, programların ve programların anlamlarını tanımlamak için kullanılır.
yapılar. Bazı dil yapıları (örneğin, ifadeler) eşlenir
devletlere değil, değerlere.
3.5.2.3 İfadeler
İfadeler çoğu programlama dili için temeldir. burada varsayıyoruz
bu ifadelerin hiçbir yan etkisi yoktur. Ayrıca, biz sadece çok
basit ifadeler: Yalnızca + ve * operatörleri vardır ve bir ifadenin
en fazla bir operatör; işlenenler yalnızca skaler tamsayı değişkenleri ve tamsayıdır
değişmezler; parantez yok; ve bir ifadenin değeri bir tamsayıdır.
Bu ifadelerin BNF açıklaması aşağıdadır:
<ifade> → <ara_sayısı> | <var> | <binary_expr>
<binary_expr> → <left_expr> <operatör> <right_expr>
<left_expr> → <dec_num> | <var>
<right_expr> → <dec_num> | <var>
<operatör> → + | *

Sayfa 167
146
Bölüm 3 Sözdizimi ve Semantiği Tanımlama
İfadelerde göz önünde bulundurduğumuz tek hata, değeri olmayan bir değişkendir.
ceza değeri. Açıkçası, başka hatalar da meydana gelebilir, ancak bunların çoğu makine-
bağımlı. Z tamsayılar kümesi olsun ve izin hata hata değeri olsun. O zamanlar
Z h { hata }, bizim için düz anlam belirtimi için anlamsal etki alanıdır.
ifade.
Belirli bir E ifadesi ve s durumu için eşleme işlevi aşağıdaki gibidir. İle
matematiksel fonksiyon tanımları ve atama arasında ayrım yapın
programlama dillerinin ifadelerinde, tanımlamak için = sembolünü kullanırız
matematiksel fonksiyonlar. Bu tanımda kullanılan ima sembolü, =>
bir işlenenin biçimini, ilişkili durum (veya anahtar) durumuyla birleştirir.
yapı. Nokta gösterimi, bir düğümün alt düğümlerini belirtmek için kullanılır. Sınav için-
ple, <binary_expr>.<left_expr>, <binary_expr> öğesinin sol alt düğümünü ifade eder.
M e (<ifade>, s) Δ = durum <ifade>
<dec_num> => M Aralık (<dec_num>, s)
<var> => VARMAP(<var>, s) == tanımsız
sonra hata
başka VARMAP(<var>, s)
<binary_expr> =>
Eğer (M E (<binary_expr>. <left_expr>, s) == undef OR
M e (<binary_expr>.<right_expr>, s) == undef )
sonra hata
else if (<binary_expr>.<operator> == '+' )
sonra M e (<binary_expr>.<left_expr>, s) +
M e (<binary_expr>.<right_expr>, s)
başka M e (<binary_expr>.<left_expr>, s) *
M e (<binary_expr>.<right_expr>, s)
3.5.2.4 Atama İfadeleri
Bir atama ifadesi, bir ifade değerlendirmesi artı
ifadenin değerine hedef değişken. Bu durumda anlam fonksiyon haritaları
bir devletten bir devlete. Bu fonksiyon aşağıdakilerle açıklanabilir:
M a (x = E, s) Δ = eğer M e (E, s) == hata
sonra hata
başka s = { < ben 1 , v 1 > , < ben 2 , v 2 > , . . . , < i n , v n > }, nerede
j = 1, 2 için. . . , n
eğer ben j == x
o zaman v j = M e (E, s)
başka v j = VARMAP(i j , s)
Yukarıdaki üçüncü son satırdaki karşılaştırmanın, i j == x, isimlere ait olduğuna dikkat edin.
değerler.

Sayfa 168
3.5 Programların Anlamlarını Tanımlamak: Dinamik Anlambilim 147
3.5.2.5 Mantıksal Ön Test Döngüleri
Mantıksal bir ön test döngüsünün düz anlamsal anlamı aldatıcı bir şekilde basittir.
Tartışmayı hızlandırmak için, mevcut iki tane daha olduğunu varsayıyoruz.
eşleme işlevleri, M sl ve M b , deyim listelerini ve durumları durumlara eşleyen
ve Boole ifadeleri , sırasıyla Boole değerlerine (veya error ) dönüştürülür. bu
fonksiyon
M l ( iken B do L, s) Δ = eğer M b (B, s) == tanımsız
sonra hata
yoksa M b (B, s) == yanlışsa
o zaman
else if M sl (L, s) == hata
sonra hata
else M l ( iken B do L, M sl (L, s))
Döngünün anlamı, basitçe, program değişkenlerinin değerden sonraki değeridir.
döngüdeki ifadeler belirtilen sayıda yürütüldü,
herhangi bir hata olmadığını varsayarsak. Özünde, döngü dönüştürüldü
yinelemeden özyinelemeye, burada özyineleme denetimi matematiksel olarak
diğer özyinelemeli durum eşleme işlevleri tarafından tanımlanır. Özyineleme daha kolaydır
yinelemeden daha matematiksel bir titizlikle tanımlayın.
Bu noktada önemli bir gözlem, bu tanımın tıpkı gerçek gibi
program döngüleri, sonlandırılmama nedeniyle hiçbir şey hesaplayamaz.
3.5.2.6 Değerlendirme
Daha önceki yapılarda kullanılanlar gibi nesneler ve işlevler,
programlama dillerinin diğer sözdizimsel varlıkları için tanımlanmıştır. Ne zaman
belirli bir dil için eksiksiz bir sistem tanımlanmıştır, kullanılabilir
o dilde tam programların anlamını belirlemek için. Bu
son derece titiz bir şekilde programlama hakkında düşünmek için bir çerçeve sağlar.
yol.
Daha önce belirtildiği gibi, düz anlambilim, lansmana yardımcı olarak kullanılabilir.
guaj tasarımı. Örneğin, düz anlamsal anlamı olan ifadeler
açıklama karmaşıktır ve zordur, tasarımcıya böyle bir
ifadeleri ayrıca dil kullanıcılarının anlaması zor olabilir ve bir
alternatif tasarım sırayla olabilir.
Düz anlam açıklamalarının karmaşıklığı nedeniyle, bunlar çok az
dil kullanıcıları için kullanın. Öte yandan, mükemmel bir yol sağlarlar.
bir dili kısaca tanımlar.
Düz anlambilimin kullanımı normalde Scott'a atfedilirse de
ve Strachey (1971), dil tanımına genel anlamsal yaklaşım
on dokuzuncu yüzyıla kadar izlenebilir (Frege, 1892).

Sayfa 169
148
Bölüm 3 Sözdizimi ve Semantiği Tanımlama
3.5.3 Aksiyomatik Semantik
Matematiksel mantığa dayandığı için bu şekilde adlandırılan aksiyomatik anlambilim ,
bu bölümde tartışılan semantik belirtimine en soyut yaklaşım.
Bir programın anlamını doğrudan belirtmek yerine, aksiyomatik anlambilim
program hakkında neyin kanıtlanabileceğini belirtir. mümkün olanlardan biri olduğunu hatırlayın.
anlamsal özelliklerin kullanım amacı, programların doğruluğunu kanıtlamaktır.
Aksiyomatik semantikte, bir makinenin veya pro-
program yürütüldüğünde meydana gelen durum değişikliklerinin gramı veya modeli.
Bir programın anlamı, program değişkenleri arasındaki ilişkilere dayanır.
ve programın her çalışması için aynı olan sabitler.
Aksiyomatik anlambilimin iki farklı uygulaması vardır: program doğrulama ve
program semantiği belirtimi. Bu bölüm program doğrulamaya odaklanır
aksiyomatik anlambilim açıklamasında.
Aksiyomatik anlambilimin gelişimi ile bağlantılı olarak tanımlanmıştır.
programların doğruluğunu kanıtlamak için bir yaklaşım. Bu tür doğruluk kanıtları,
oluşturulabildiklerinde, bir programın hesaplamayı gerçekleştirdiğini gösterin
spesifikasyonu ile açıklanmıştır. Bir ispatta, bir programın her bir ifadesi hem
önce ve ardından pro-
gram değişkenleri. Bunlar, soyut bir makinenin tüm durumundan ziyade (
operasyonel semantik ile), ifadenin anlamını belirtmek için kullanılır.
Kısıtlamaları tanımlamak için kullanılan gösterim - aslında, aksiyomatik
anlambilim — yüklem hesabıdır. Her ne kadar basit Boole ifadeleri
genellikle kısıtlamaları ifade etmek için yeterlidir, bazı durumlarda değildir.
Aksiyomatik anlambilim, bir ifadenin anlamını biçimsel olarak belirtmek için kullanıldığında,
ifade, anlam ifadenin iddialar üzerindeki etkisi ile tanımlanır.
açıklamadan etkilenen veriler.
3.5.3.1 İddialar
Aksiyomatik anlambilimde kullanılan mantıksal ifadelere yüklemler veya
iddialar . Bir program ifadesinin hemen önündeki bir iddia,
programın o noktasında program değişkenleri üzerindeki kısıtlamalar. bir iddia-
Bir ifadenin hemen ardından gelen tion, bunlar üzerindeki yeni kısıtlamaları açıklar.
ifadenin yürütülmesinden sonra değişkenler (ve muhtemelen diğerleri). Bu iddia-
duruma sırasıyla önkoşul ve sonkoşul denir.
ment. İki bitişik ifade için, birincinin son koşulu,
ikincisinin ön koşulu. Aksiyomatik bir açıklama veya kanıt geliştirme
Belirli bir program, programdaki her ifadenin hem ön
koşul ve bir son koşul.
Aşağıdaki bölümlerde, iddiaları bakış açısından inceleyeceğiz.
ifadeler için ön koşulların verilen son koşullardan hesaplandığını,
bunları tam tersi anlamda değerlendirmek mümkün olsa da. hepsini varsayıyoruz
değişkenler tamsayı tipindedir. Basit bir örnek olarak, aşağıdaki atamayı düşünün-
ment deyimi ve sonkoşul:
toplam = 2 * x + 1 {toplam > 1}

sayfa 170
3.5 Programların Anlamlarını Tanımlamak: Dinamik Anlambilim 149
Önkoşul ve sonkoşul iddiaları, ayırt etmek için parantez içinde sunulur.
onları program ifadelerinin bölümlerinden kurtarın. için olası bir ön koşul
bu ifade { x > 10 }'dir.
Aksiyomatik anlambilimde, belirli bir ifadenin anlamı şu şekilde tanımlanır:
onun önkoşulu ve onun sonkoşulu. Gerçekte, iki iddia ön-
kesinlikle ifadeyi yürütmenin etkisi.
Aşağıdaki alt bölümlerde, ifadelerin doğruluk kanıtlarına odaklanıyoruz.
ve aksiyomatik anlambilimin yaygın bir kullanımı olan programlar. Daha çok gen-
Aksiyomatik anlambilimin genel kavramı, durumun tam olarak anlamını ifade etmektir.
mantıksal ifadeler açısından mentler ve programlar. Program doğrulama bir
dillerin aksiyomatik tanımlarının uygulanması.
3.5.3.2 En Zayıf Ön Koşullar
En zayıf önkoşul , garanti edecek en az kısıtlayıcı önkoşuldur.
ilişkili son koşulun geçerliliğini önleyin. Örneğin, devlet-
Bölüm 3.5.3.1, { x > 10 }, { x > 50 } ve
{ x > 1000 } tümü geçerli ön koşullardır. Tüm ön koşulların en zayıfı
bu durum { x > 0 }.
En zayıf önkoşul en genel olandan hesaplanabiliyorsa
bir dilin ifade türlerinin her biri için sonkoşul, ardından pro-
Bu ön koşulları hesaplamak için kullanılan işlemler, aşağıdakilerin kısa bir tanımını sağlar:
o dilin semantiği. Ayrıca, doğruluk kanıtları,
o dilde programlar için yapılandırılmıştır. kullanılarak bir program kanıtı başlatılır.
son koşul olarak programın yürütülmesinin sonuçlarının özellikleri
programın son açıklaması. Bu son koşul, son koşulla birlikte
deyimi, son deyim için en zayıf ön koşulu hesaplamak için kullanılır.
Bu ön koşul daha sonra ikinci son durum için son koşul olarak kullanılır.
ment. Bu işlem programın başlangıcına ulaşılana kadar devam eder.
Bu noktada, ilk ifadenin ön koşulu, koşulları belirtir.
altında programın istenen sonuçları hesaplayacağı. Bu koşullar ise
programın girdi özelliği tarafından ima edilirse, program
doğru olduğu doğrulandı.
Bir çıkarım kuralı , bir iddianın doğruluğunu çıkarsama yöntemidir.
diğer iddiaların değerlerinin temeli. Bir çıkarımın genel biçimi
kural aşağıdaki gibidir:
S1, S2, c , Sn
S
Bu kural, eğer S1, S2, . . . , ve S n doğrudur, o zaman S'nin gerçeği şu olabilir:
çıkarsanan. Bir çıkarım kuralının üst kısmına onun öncülü denir ; alt
parçasına onun sonucu denir .
Bir aksiyom , doğru olduğu varsayılan mantıksal bir ifadedir. Bu nedenle, bir
aksiyom, öncülü olmayan bir çıkarım kuralıdır.
Bazı program ifadeleri için, en zayıf ön koşulun hesaplanması
ifadeden ve bir son koşul basittir ve bir

Sayfa 171
150
Bölüm 3 Sözdizimi ve Semantiği Tanımlama
aksiyom. Ancak çoğu durumda, en zayıf ön koşul yalnızca belirtilebilir.
bir çıkarım kuralı ile.
Belirli bir programlama dili ile aksiyomatik semantiği kullanmak,
doğruluk kanıtları veya biçimsel anlamsal özellikler için, ya bir aksiyom
veya dilde her bir ifade türü için bir çıkarım kuralı bulunmalıdır. İçinde
Aşağıdaki alt bölümlerde, atama ifadeleri için bir aksiyom sunuyoruz ve
deyim dizileri, seçim deyimleri ve mantıksal ön
test döngüsü ifadeleri. Ne aritmetik ne de Boolean olduğunu varsaydığımıza dikkat edin.
ifadelerin yan etkileri vardır.
3.5.3.3 Atama Beyanları
Bir atama ifadesinin önkoşulu ve sonkoşulu birlikte
anlamını tam olarak tanımlayın. Bir atama durumunun anlamını tanımlamak için-
bir sonkoşul verildiğinde, onun önkoşulunu hesaplamanın bir yolu olmalıdır.
bu son koşuldan.
x = E genel bir atama ifadesi ve Q onun sonkoşulu olsun.
Daha sonra, önkoşulu P, aksiyom tarafından tanımlanır.
P = S xSE
bu, P'nin, tüm x örneklerinin E ile değiştirildiği Q olarak hesaplandığı anlamına gelir.
örneğin, atama ifademiz ve son koşulumuz varsa
a = b / 2 - 1 {a < 10}
zayıf ön koşulu ile değiştirilmesiyle hesaplanır 1 - b / 2 için bir in
sonkoşul { a < 10 }, aşağıdaki gibi:
b / 2 - 1 < 10
b < 22
Böylece, verilen atama ifadesi ve sonrası için en zayıf ön koşul
koşul { b < 22 }. Atama aksiyomunun garanti edildiğini unutmayın.
sadece yan etkilerin yokluğunda doğru olun. Bir atama ifadesinin bir
hedefinden başka bir değişkeni değiştirirse yan etki.
Belirli bir durumun aksiyomatik semantiğini belirtmek için olağan gösterim-
ment formu
{P}S{Q}
burada P ön koşul, Q son koşul ve S ifadedir
form. Atama ifadesi durumunda, gösterim şu şekildedir:
{ Q xSE } x = E {Q}

Sayfa 172
3.5 Programların Anlamlarını Tanımlamak: Dinamik Semantik 151
Bir atama durumu için bir önkoşul hesaplamanın başka bir örneği olarak-
aşağıdakileri göz önünde bulundurun:
x = 2 * y - 3 {x > 25}
Ön koşul aşağıdaki gibi hesaplanır:
2 * y - 3 > 25
y > 14
Yani { y > 14 } bu atama ifadesi için en zayıf önkoşuldur ve
sonkoşul.
Atama ifadesinin sol tarafının görünümünün,
sağ taraf, en zayıf ön koşulu hesaplama sürecini etkilemez.
örneğin, için
x = x + y - 3 {x > 10}
en zayıf ön koşul
x + y - 3 > 10
y > 13 - x
Aksiyomatik anlambilimin doğruluğunu kanıtlamak için geliştirildiğini hatırlayın.
programlar. Bunun ışığında, bu noktada aksiyomun nasıl olduğunu merak etmek doğaldır.
for atama ifadeleri herhangi bir şeyi kanıtlamak için kullanılabilir. İşte nasıl: Verilen bir
hem ön koşullu hem de son koşullu atama ifadesi kon-
mantıksal bir ifade ya da teoremi seçti. Atama aksiyomu uygulandığında
son koşula ve atama ifadesine, verilen ön-
koşul, teorem kanıtlanmıştır. Örneğin, mantıksal ifadeyi düşünün
{x > 3} x = x - 3 {x > 0}
Atama aksiyomunu kullanma
x = x - 3 {x > 0}
verilen önkoşul olan { x > 3 } üretir . Bu nedenle, kanıtladık
örnek mantıksal ifade.
Ardından, mantıksal ifadeyi düşünün
{x > 5} x = x - 3 {x > 0}
Bu durumda, verilen ön koşul, { x > 5 }, iddia ile aynı değildir.
aksiyom tarafından üretilir. Ancak, { x > 5 } ifadesinin { x > 3 } anlamına geldiği açıktır .

Sayfa 173
152
Bölüm 3 Sözdizimi ve Semantiği Tanımlama
Adında bir kanıtı, bir çıkarsama kuralı, bu kullanmak için sonucu üstünlüğü vardır
gerekli. Sonuç kuralının şekli
{P} S {Q}, P=> P, Q => Q
{P} S {Q}
=> Sembol araçları “ima” ve S herhangi bir program deyimi olabilir. Kural
aşağıdaki gibi ifade edilebilir: Mantıksal ifade {P} S {Q} doğruysa, iddia
P, P iddiasını ima eder ve Q iddiası Q iddiasını ima eder, o zaman
{P} S {Q} olduğu çıkarılabilir. Başka bir deyişle, sonuç kuralı diyor ki
bir sonkoşul her zaman zayıflatılabilir ve bir önkoşul her zaman olabilir
güçlendirilmiş. Bu, program kanıtlarında oldukça kullanışlıdır. Örneğin, izin verir
Yukarıdaki son mantıksal ifade örneğinin ispatının tamamlanması. P'ye izin verirsek
{ x > 3 } olsun, Q ve Q { x > 0 } olsun ve P { x > 5 } olsun, elimizde
{x>3}x = x–3{x>0},(x>5) => {x>3},(x>0) => (x>0)
{x>5}x = x–3{x>0}
Öncülün ilk terimi ( {x > 3} x = x – 3 {x > 0} ) ispatlandı
atama aksiyomu ile İkinci ve üçüncü terimler açıktır. Orası-
çünkü sonuç kuralına göre sonuç doğrudur.
3.5.3.4 Diziler
Bir ifade dizisi için en zayıf önkoşul şu şekilde tanımlanamaz:
bir aksiyom, çünkü önkoşul belirli durum türlerine bağlıdır.
sırada yer alır. Bu durumda, önkoşul yalnızca şu şekilde açıklanabilir:
bir çıkarım kuralı. S1 ve S2 bitişik program ifadeleri olsun. S1 ve S2 ise
aşağıdaki ön ve son koşullara sahip
{P1} S1 {P2}
{P2} S2 {P3}
böyle bir iki ifade dizisi için çıkarım kuralı
{P1} S1 {P2}, {P2} S2 {P3}
{P1} S1, S2 {P3}
Örneğimiz için {P1} S1; S2 {P3}, aşağıdakilerin aksiyomatik semantiğini tanımlar
S1 dizisi; S2. Çıkarım kuralı, diziyi önceden elde etmek için şunu belirtir:
koşul, ikinci ifadenin ön koşulu hesaplanır. Bu yeni
iddia daha sonra ilk ifadenin son koşulu olarak kullanılır;
daha sonra ilk ifadenin ön koşulunu hesaplamak için kullanılır, ki bu
ayrıca tüm dizinin ön koşulu. S1 ve S2 atama ise
ifadeler

Sayfa 174
3.5 Programların Anlamlarını Tanımlamak: Dinamik Semantik 153
x1= E1
ve
x2= E2
o zaman bizde
{P3 x2SE2 } x2= E2 {P3}
{(P3 x2SE2 ) x1SE1 } x1= E1 {P3 x2SE2 }
Bu nedenle, x1 = E1 dizisi için en zayıf önkoşul ; x2 = E2 ile
sonkoşul P3, {(P3 x2SE2 ) x1SE1 }'dir.
Örneğin, aşağıdaki diziyi ve son koşulu göz önünde bulundurun:
y = 3 * x + 1;
x = y + 3;
{x < 10}
İkinci atama ifadesinin ön koşulu şudur:
y < 7
bu, ilk ifade için son koşul olarak kullanılır. için ön koşul
ilk atama ifadesi şimdi hesaplanabilir:
3 * x + 1 < 7
x < 2
Yani, {x < 2} , hem ilk ifadenin hem de iki ifadenin ön koşuludur.
ifade dizisi.
3.5.3.5 Seçim
Daha sonra seçim ifadeleri için çıkarım kuralını, genel formu ele alacağız.
hangisi
eğer B sonra S1 başka S2
Yalnızca else yan tümcelerini içeren seçimleri dikkate alıyoruz . çıkarım kuralı
{B ve P} S1 {Q}, {(B değil) ve P} S2{Q}
{P} eğer B daha sonra S1 başka S2 {Q}
Bu kural, seçim ifadelerinin kanıtlanması gerektiğini belirtir.
Boolean kontrol ifadesi doğrudur ve yanlış olduğunda. İlk mantıksal durum-
satırın üstündeki ment, then yan tümcesini temsil eder ; İkinci temsil eder Başka

Sayfa 175
154
Bölüm 3 Sözdizimi ve Semantiği Tanımlama
madde. Çıkarım kuralına göre, olabilecek bir P ön koşuluna ihtiyacımız var.
Her iki koşul kullanılan sonra ve başka maddeleri.
Aşağıdaki ön koşulun hesaplanması örneğini göz önünde bulundurun
seçim çıkarım kuralını kullanarak. Örnek seçim ifadesi
eğer x> 0 ardından
y = y - 1
Başka
y = y + 1
Bu seçim ifadesi için sonkoşul Q'nun { y > 0 } olduğunu varsayalım . Biz
üzerinde atama için belitini kullanabilirsiniz ardından maddesinin
y = y - 1 {y > 0}
Bu, { y - 1 > 0 } veya { y > 1 } üretir . P parçası olarak kullanılabilir.
sonra yan tümcesi için ön koşul . Şimdi aynı aksiyomu uyguluyoruz
için başka maddede
y = y + 1 {y > 0}
bu, { y + 1 > 0 } veya { y > -1 } ön koşulunu üretir .
{ y > 1 } = > { y > -1 } olduğundan, sonuç kuralı,
tüm seçim ifadesinin ön koşulu için { y > 1 } kullanın .
3.5.3.6 Mantıksal Ön Test Döngüleri
Zorunlu programlama dillerinin bir başka temel yapısı
mantıksal ön test veya while döngüsüdür. En zayıf ön hesaplama
bir süre döngüsü için koşul , doğası gereği için olduğundan daha zordur
bir dizi, çünkü yineleme sayısı her zaman olamaz
önceden belirlenmiş. Yineleme sayısının bilindiği bir durumda,
döngü açılabilir ve bir dizi olarak ele alınabilir.
Döngüler için en zayıf ön koşulu hesaplama sorunu benzerdir.
tüm pozitif tamsayılar hakkında bir teoremi kanıtlama sorununa. Sonrakinde, bir diğerinde, sonra gelende
durumda, indüksiyon normalde kullanılır ve aynı endüktif yöntem aşağıdakiler için kullanılabilir:
bazı döngüler. Tümevarımdaki temel adım, tümevarımsal bir hipotez bulmaktır.
Bir while döngüsünün aksiyomatik semantiğindeki karşılık gelen adım,
en zayıf olanı bulmak için çok önemli olan döngü değişmezi adı verilen bir iddia
ön koşul.
Bir while döngüsü için ön koşulu hesaplamak için çıkarım kuralı şudur:
{I ve B} S {I}
{I} ise B do S ucu {I ve (değil B)}
burada döngü değişmezi. Bu basit görünüyor, ama değil. Karmaşıklık
uygun bir döngü değişmezi bulmakta yatar.
tarih notu
Önemli miktarda iş
ihtimal üzerine yapılmıştır
anlamsal dil kullanmanın
oluşturulacak açıklamalar
derleyiciler otomatik olarak (Jones,
1980; Milos ve diğerleri, 1984;
Bodwin ve diğerleri, 1982). Bunlar
çabalar göstermiştir ki,
yöntem uygulanabilir, ancak iş
hiç ilerlemedi
kullanılabileceği nokta
yararlı derleyiciler oluşturun.

Sayfa 176
3.5 Programların Anlamlarını Tanımlamak: Dinamik Anlambilim 155
Bir while döngüsünün aksiyomatik açıklaması şu şekilde yazılır:
{P} ise B do S ucu {S}
Döngü değişmezinin yararlı olması için bir dizi gereksinimi karşılaması gerekir.
İlk olarak, while döngüsü için en zayıf ön koşul gerçeği garanti etmelidir.
döngü değişmez. Buna karşılık, döngü değişmezi aşağıdakilerin doğruluğunu garanti etmelidir.
döngü sonlandırması üzerine son koşul. Bu kısıtlamalar bizi
aksiyomatik açıklamaya çıkarım kuralı. Döngünün yürütülmesi sırasında,
döngü değişmezinin doğruluğu, döngünün değerlendirilmesinden etkilenmemelidir.
Boole ifadesini ve döngü gövdesi ifadelerini kontrol etme. Bu nedenle, adı
değişmez.
while döngüleri için bir başka karmaşık faktör , döngü termi-
ulus. Sonlanmayan bir döngü doğru olamaz ve aslında
Hiçbir şey. Q, döngü çıkışından hemen sonra geçerli olan son koşul ise, o zaman
döngü için bir ön koşul P, döngü çıkışında Q'yu garanti eden ve ayrıca
döngünün sona erdiğini garanti eder.
Bir while yapısının tam aksiyomatik açıklaması, aşağıdakilerin tümünü gerektirir:
aşağıdakiler doğru, ki burada ben döngü değişmezi:
P => ben
{I ve B} S {I}
(I ve (B değil)) => Q
döngü sona erer
Bir döngü bir dizi sayısal değer hesaplıyorsa, bulmak mümkün olabilir.
endüktifi belirlemek için kullanılan bir yaklaşımı kullanan bir döngü değişmezi
hakkında bir ifadeyi kanıtlamak için matematiksel tümevarım kullanıldığında hipotez
matematiksel bir dizi. yineleme sayısı arasındaki ilişki
ve döngü gövdesi için önkoşul, birkaç durum için şu şekilde hesaplanır:
genel durum için geçerli olacak bir modelin ortaya çıkmasını umuyoruz. Yardımcı olur
en zayıf ön koşulu üretme sürecini bir fonksiyon olarak ele almak, wp. İçinde
Genel
wp(ifade, sonkoşul) = önkoşul
Bir wp işlevine genellikle yüklem dönüştürücü denir , çünkü bir yüklem alır.
parametre olarak cate veya onaylamadır ve başka bir yüklemi döndürür.
I'yi bulmak için, önkoşulları hesaplamak için Q döngüsü son koşulu kullanılır.
hiçbiri ile başlayan döngü gövdesinin birkaç farklı yinelemesi. Eğer
döngü gövdesi, atama aksiyomu olan tek bir atama ifadesi içerir.
ment ifadeleri bu durumları hesaplamak için kullanılabilir. Örneği düşünün
döngü:
while y <> x do y = y + 1 bitiş {y = x}
Burada eşittir işaretinin iki farklı amaç için kullanıldığını unutmayın.
İddialarda matematiksel eşitlik anlamına gelir; dış iddialar, bu demektir
atama operatörü.

Sayfa 177
156
Bölüm 3 Sözdizimi ve Semantiği Tanımlama
Sıfır yineleme için en zayıf ön koşul, açıkçası,
{y = x}
Bir yineleme için,
wp (y = y + 1, {y = x}) = {y + 1 = x} veya {y = x - 1}
İki yineleme için,
wp (y = y + 1, {y = x - 1})={y + 1 = x - 1} veya {y = x - 2}
Üç yineleme için,
wp (y = y + 1, {y = x - 2})={y + 1 = x - 2} veya {y = x – 3}
{ y < x } öğesinin bir veya daha fazla yinelemenin olduğu durumlar için yeterli olacağı artık açıktır .
Bunu sıfır yineleme durumu için { y = x } ile birleştirerek { y <= x } elde ederiz ,
hangi döngü değişmezi için kullanılabilir. while durumu için bir ön koşul-
ment, döngü değişmezinden belirlenebilir. Aslında, ben olarak kullanılabilir
ön koşul, P.
Seçimimizin I için dört kriteri karşıladığından emin olmalıyız.
örnek döngü. Birincisi, çünkü P = I, P => I. İkinci şart ise,
doğru olmalı ki
{I ve B} S {I}
Örneğimizde, elimizde
{y <= x ve y <> x} y = y + 1 {y <= x}
Atama aksiyomunun uygulanması
y = y + 1 {y <= x}
elde ederiz { y + 1 <= X }, eşdeğer olan { y <x } ima edildiği
{ y <= x ve y <> x }. Yani, önceki ifade kanıtlanmıştır.
Sonra, sahip olmalıyız
{I ve (B değil)} => Q
Örneğimizde, elimizde
{(y <= x) ve değil (y <> x)} => {y = x}
{(y <= x) ve (y = x)} => {y = x}
{y = x} => {y = x}
Yani, bu açıkça doğrudur. Ardından, döngü sonlandırması dikkate alınmalıdır. Bunda
örneğin, soru döngü olup olmadığıdır.
{y <= x} while y <> x do y = y + 1 bitiş {y = x}

Sayfa 178
3.5 Programların Anlamlarını Tanımlamak: Dinamik Semantik 157
sona erer. x ve y'nin tamsayı değişkenleri olarak kabul edildiğini hatırlayarak , bu kolay
bu döngünün sona erdiğini görmek için. Ön koşul, y'nin başlatıldığını garanti eder.
tially x'ten büyük değil . Döngü gövdesi artışlarla y her bir tekranyla kadar
y , x'e eşittir . Başlangıçta y , x'ten ne kadar küçük olursa olsun , eşit olacaktır.
aslında x'e eşit olur . Böylece döngü sona erecektir. Çünkü bizim seçimimiz ben
dört kriteri de karşılar, tatmin edici bir döngü değişmezi ve döngü ön koşuludur.
Bir döngü için değişmezi hesaplamak için kullanılan önceki süreç,
her zaman en zayıf önkoşul olan bir iddia üretin (olmasına rağmen
örnekte).
Kullanılan yaklaşımı kullanarak bir döngü değişmezi bulmanın başka bir örneği olarak
matematiksel tümevarım, aşağıdaki döngü ifadesini göz önünde bulundurun:
while s > 1 do s = s / 2 bitiş {s = 1}
Daha önce olduğu gibi, bir döngü değişmezi ve bir döngü bulmaya çalışmak için atama aksiyomunu kullanırız.
döngü için ön koşul. Sıfır yinelemeler için en zayıf ön koşul
{ s = 1 }. Bir yineleme için,
wp (s = s / 2, {s = 1}) = {s / 2 = 1} veya {s = 2}
İki yineleme için,
wp (s = s / 2, {s = 2}) = {s / 2 = 2} veya {s = 4}
Üç yineleme için,
wp (s = s / 2, {s = 4}) = {s / 2 = 4} veya {s = 8}
Bu durumlardan, değişmezin olduğunu açıkça görebiliriz.
{ s , 2'nin negatif olmayan bir kuvvetidir }
Bir kez daha, hesaplanan I, P olarak hizmet edebilir ve dört gereksinimi geçerim.
Daha önceki döngü önkoşul bulma örneğimizden farklı olarak, bu açıkça şudur:
en zayıf ön koşul değildir. { s > 1 } ön koşulunu kullanmayı düşünün . bu
mantıksal ifade
{s > 1} iken s > 1 do s = s / 2 bitiş {s = 1}
kolayca kanıtlanabilir ve bu ön koşul,
biri daha önce hesaplandı. Herhangi bir pozitif için döngü ve ön koşul karşılanır
s için değer , işlemin gösterdiği gibi yalnızca 2'nin kuvvetleri değil. kuralı nedeniyle
Sonuç olarak, en zayıf önkoşuldan daha güçlü bir önkoşul kullanmak
olması bir ispatı geçersiz kılmaz.
Döngü değişmezlerini bulmak her zaman kolay değildir. anlamakta fayda var
bu değişmezlerin doğası. İlk olarak, bir döngü değişmezi, döngünün zayıflamış bir versiyonudur.
döngü sonkoşulu ve ayrıca döngü için bir önkoşul. Yani zayıf olmalıyım
döngü yürütmenin başlangıcından önce tatmin olmak için yeterli, ancak ne zaman
döngü çıkış koşuluyla birleştirildiğinde, döngüyü zorlayacak kadar güçlü olmalıdır.
son koşulun gerçeği.

Sayfa 179
158
Bölüm 3 Sözdizimi ve Semantiği Tanımlama
Döngü sonlandırmasının kanıtlanmasının zorluğu nedeniyle, bu gereksinim
çoğu zaman göz ardı edilir. Döngü sonlandırması gösterilebilirse, aksiyomatik açıklama
döngünün toplam doğruluğu denir . Diğer şartlar sağlanabiliyorsa ancak
sonlandırma garanti edilmez, buna kısmi doğruluk denir .
Daha karmaşık döngülerde, kısmi döngüler için bile uygun bir döngü değişmezi bulma
doğruluk, büyük bir ustalık gerektirir. Çünkü ön hesaplama
while döngüsü için koşul, döngünün değişmezliğini kanıtlayan bir döngü bulmaya bağlıdır.
aksiyomatik semantiği kullanan while döngülü programların doğruluğu
zor.
3.5.3.7 Program Kanıtları
Bu bölüm, iki basit program için doğrulama sağlar. ilk örnek
doğruluk kanıtının bir dizisinden oluşan çok kısa bir program içindir.
iki değişkenin değerlerini değiştiren üç atama ifadesi.
{x = A VE y = B}
t = x;
x = y;
y = t;
{x = B VE y = A}
Program tamamen atama ifadelerinden oluştuğu için
dizi, atama aksiyomu ve diziler için çıkarım kuralı olabilir
doğruluğunu kanıtlamak için kullanılır. İlk adım, atama aksiyomunu kullanmaktır.
tüm program için son ifade ve son koşul. Bu verim
ön koşul
{x = B VE t = A}
Daha sonra, bu yeni ön koşulu orta durumda bir son koşul olarak kullanırız.
ment ve önkoşulunu hesaplayın, ki bu
{y = B VE t = A}
Daha sonra, bu yeni iddiayı ilk ifadede son koşul olarak kullanırız.
ve sonuç veren atama aksiyomunu uygulayın
{y = B VE x = A}
sırası dışında, programdaki ön koşulla aynıdır.
AND operatörü üzerinde işlenenler . Çünkü VE simetrik operatörü, bizim kanıtı
tamamlandı.
Aşağıdaki örnek, bir sözde kod programının doğruluğunun bir kanıtıdır.
faktöriyel fonksiyonu hesaplar.

sayfa 180
3.5 Programların Anlamlarını Tanımlama: Dinamik Semantik 159
{n >= 0}
sayı = n;
gerçek = 1;
sayarken <> 0 yap
gerçek = gerçek * sayı;
say = say - 1;
son
{gerçek = n!}
Döngü değişmezini bulmak için daha önce açıklanan yöntem,
bu örnekteki döngü. Burada yardımcı olabilecek bir miktar ustalık gereklidir.
kodun kısa bir çalışması ile. Döngü, faktöriyel işlevi sırayla hesaplar
önce son çarpmanın; yani, * n - (1 n) varsayarak birinci yapılır n
daha büyüktür 1 . Yani, değişmezin bir parçası olabilir
gerçek = (sayım + 1) * (sayım + 2) * . . . * (n - 1) * n
Ama aynı zamanda sağlamalıdır sayımı Yapabileceğimiz hangi daima negatif olmayan bir
bunu yukarıdaki iddiaya ekleyerek, elde etmek için
I = (gerçek = (sayı + 1) * . . . * n) VE (sayım >= 0)
Ardından, bunun değişmezler için gereksinimleri karşıladığını doğrulamalıyız.
Bir kez daha I'in P için kullanılmasına izin verdik, dolayısıyla P açıkça I'yi ima ediyor. Sonraki soru
durum
{I ve B} S {I}
ben ve B
((gerçek = (sayım + 1) * . . . * n) VE (sayım >= 0) VE
(sayım <> 0)
hangi azaltır
(gerçek = (sayı + 1) * . . . * n) VE (sayı > 0)
Bizim durumumuzda, kullanarak döngü gövdesinin ön koşulunu hesaplamalıyız.
sonkoşul için değişmez. İçin
{P} sayı = sayı - 1 {I}
P olarak hesaplıyoruz
{(gerçek = sayı * (sayım + 1) * . . . * n) VE
(sayım >= 1)}

Sayfa 181
160
Bölüm 3 Sözdizimi ve Semantiği Tanımlama
Bunu döngü gövdesindeki ilk atama için son koşul olarak kullanarak,
{P} gerçek = gerçek * sayı {(gerçek = sayı * (sayım + 1)
* . . . * n) VE (sayı >= 1)}
Bu durumda, P
{(gerçek = (sayım + 1) * . . . * n) VE (sayım >= 1)}
I ve B'nin bu P'yi ima ettiği açıktır, dolayısıyla sonuç kuralına göre,
{I VE B} S { Ben }
doğru. Son olarak, I'in son testi
I VE ( B DEĞİL ) = > Q
Örneğimiz için bu
((gerçek = (sayım + 1) * . . . * n) VE (sayım >= 0) VE
(sayı = 0)) => gerçek = n!
Bu açıkça doğrudur, çünkü count = 0 olduğunda, ilk kısım tam olarak tanımdır.
faktöriyel. Bu nedenle, I seçimimiz bir döngü değişmezi için gereksinimleri karşılar.
Şimdi dan (I ile aynıdır) bizim P kullanabilirsiniz süre postcon- olarak
programın ikinci atamasında
{P} gerçek = 1 {(gerçek = (sayı + 1) * . . . * n) VE
(sayım >= 0)}
P için hangi verim
(1 = (sayım + 1) * . . . * n) VE (sayım >= 0))
Bunu koddaki ilk atama için son koşul olarak kullanmak
{P} sayı = n {(1 = (sayı + 1) * . . . * n) VE
(sayım >= 0)))}
P için üretir
{(n + 1) * . . . * n = 1) VE (n >= 0)}
AND operatörünün sol işleneni true (çünkü 1 = 1 ) ve sağ işlenen
işlenen tam olarak tüm kod segmentinin ön koşuludur, { n >= 0 }.
Bu nedenle, programın doğru olduğu kanıtlanmıştır.
3.5.3.8 Değerlendirme
Daha önce belirtildiği gibi, eksiksiz bir programlama dilinin anlambilimini tanımlamak için
aksiyomatik yöntemi kullanarak ölçün, bir aksiyom veya çıkarım kuralı olmalıdır
dildeki her ifade türü için. Aksiyomları veya çıkarım kurallarını tanımlama

Sayfa 182
Bibliyografik Notlar 161
programlama dillerinin bazı ifadelerinin zor olduğu kanıtlanmıştır.
görev. Bu soruna bariz bir çözüm, dili şu şekilde tasarlamaktır:
aksiyomatik yöntem akılda tutulur, böylece yalnızca aksiyomların veya çıkarımların yapıldığı ifadeler
yazılabilen kurallar yer almaktadır. Ne yazık ki, böyle bir dil
mutlaka bazı yararlı ve güçlü parçaları dışarıda bırakın.
Aksiyomatik anlambilim, program düzeltme araştırmaları için güçlü bir araçtır.
ness kanıtları ve üzerinde akıl yürütmek için mükemmel bir çerçeve sağlar.
Programlar, hem yapımları sırasında hem de sonrasında. Açıklamadaki faydası
programlama dillerinin dil kullanıcıları ve derleyici yazarları için anlamı
ancak oldukça sınırlıdır.
ÖZET
Backus-Naur Formu ve bağlamdan bağımsız gramerler eşdeğer metadillerdir
programlama dilinin sözdizimini tanımlama görevi için çok uygundur.
göstergeler. Bunlar yalnızca kısa ve öz tanımlayıcı araçlar değil, aynı zamanda ayrıştırma ağaçlarıdır.
Üretken eylemleriyle ilişkilendirilebilen, grafiksel kanıt sağlar.
temel sözdizimsel yapılar. Ayrıca, doğal olarak ilişkili oldukları
ürettikleri diller için tanıma cihazları, bu da ilişkiye yol açar.
bu diller için derleyiciler için sözdizimi çözümleyicilerinin oldukça kolay yapısı.
Nitelik dilbilgisi, hem
bir dilin sözdizimi ve statik anlambilimi. Nitelik gramerleri uzantılardır
bağlamdan bağımsız gramerlere. Nitelik dilbilgisi bir dilbilgisinden, bir dilbilgisi kümesinden oluşur.
öznitelikler, bir dizi öznitelik hesaplama işlevi ve bir dizi yüklem,
bunlar birlikte statik anlambilim kurallarını tanımlar.
Bu bölüm, üç anlambilim yöntemine kısa bir giriş sağlar.
tanım: operasyonel, düz anlamsal ve aksiyomatik. işlemsel anlambilim
dil yapılarının anlamlarını kendi açılarından tanımlamanın bir yöntemidir.
ideal bir makine üzerindeki etkiler. Düz anlambilimde, matematiksel nesneler
dil yapılarının anlamlarını temsil etmek için kullanılır. Dil varlıkları
özyinelemeli fonksiyonlarla bu matematiksel nesnelere dönüştürülür. aksiyomatik
biçimsel mantığa dayanan anlambilim,
programların doğruluğu
KAYNAKÇA NOTLAR
Bağlamdan bağımsız gramerleri ve BNF'yi kullanan sözdizimi açıklaması, tamamen geçersiz kılınmıştır.
Cleaveland ve Uzgalis'te (1976) tartışılmıştır.
Aksiyomatik anlambilim üzerine araştırmalar Floyd (1967) tarafından başlatıldı ve
Hoare (1969) tarafından geliştirilmiştir. Pascal'ın büyük bir bölümünün semantiği,
Hoare ve Wirth (1973) tarafından bu yöntem kullanılarak tarif edilmiştir. Yaptıkları parçalar
ilgili fonksiyonel yan etkileri ve goto ifadelerini tamamlamaz. Bunlar
tarif edilmesi en zor olanıdır.

Sayfa 183
162
Bölüm 3 Sözdizimi ve Semantiği Tanımlama
Geliştirme sırasında ön koşulları ve son koşulları kullanma tekniği
Programların açıklanması Dijkstra (1976) tarafından tarif edilmiş (ve savunulmuş) ve ayrıca
Gries'te (1981) ayrıntılı olarak tartışılmıştır.
Düz anlamsal semantik için iyi tanıtımlar Gordon'da bulunabilir
(1979) ve Stoy (1977). Tüm semantik tanımlama yöntemlerine giriş
Bu bölümde tartışılan Marcotty ve ark. (1976). başka bir iyi
bölüm materyalinin çoğu için referans Pagan'dır (1981). deno-
bu bölümdeki anlamsal anlamsal işlevler, Meyer'de (1990) bulunana benzer.
İNCELEME SORULARI
1. Sözdizimi ve anlambilimi tanımlayın .
2. Dil açıklamaları kimler içindir?
3. Genel bir dil üretecinin çalışmasını tanımlayın.
4. Genel bir dil tanıyıcının çalışmasını açıklayın.
5. Cümle ile cümle formu arasındaki fark nedir?
6. Sola özyinelemeli bir dilbilgisi kuralı tanımlayın.
7. Çoğu EBNF'de ortak olan üç uzantı nedir?
8. Statik ve dinamik anlambilim arasında ayrım yapın.
9. Bir nitelik dilbilgisinde yüklemler hangi amaca hizmet eder?
10. Sentezlenmiş ve kalıtsal nitelik arasındaki fark nedir?
11. Bir ağacın ağaçları için niteliklerin değerlendirilme sırası nasıl belirlenir?
verilen nitelik dilbilgisi?
12. Nitelik gramerlerinin birincil kullanımı nedir?
13. Tanımlamak için bir metodolojinin ve gösterimin birincil kullanımlarını açıklayın
programlama dillerinin semantiği.
14. İşlemdeki ifadeleri tanımlamak için neden makine dilleri kullanılamıyor?
semantik?
15. İşlemsel anlambilimin iki kullanım düzeyini tanımlayın.
16. Düz anlambilimde sözdizimsel ve anlamsal alanlar nelerdir?
17. Düz anlamsal anlambilim için bir programın durumunda ne saklanır?
18. En yaygın olarak bilinen anlambilim yaklaşımı hangisidir?
19. Her dil varlığı için hangi iki şeyin tanımlanması gerekir?
dilin düz anlamsal bir tanımını oluşturuyor musunuz?
20. Bir çıkarım kuralının hangi kısmı öncüldür?
21. Bir yüklem dönüştürücü işlevi nedir?
22. Bir döngü yapısı için kısmi doğruluk ne anlama gelir?
23. Aksiyomatik anlambilim, matematiğin hangi dalına dayanmaktadır?
24. Düz anlamsal anlambilim, matematiğin hangi dalına dayanmaktadır?

Sayfa 184
Problem Seti 163
25. Operatör için salt bir yazılım yorumlayıcısı kullanmanın sorunu nedir?
semantik?
26. Belirli bir ifadenin ön koşullarının ve son koşullarının ne olduğunu açıklayın
aksiyomatik anlambilimde ortalama.
27. Doğruluğunu kanıtlamak için aksiyomatik anlambilim kullanma yaklaşımını tanımlayın.
Belirli bir programın niteliği.
28. Düz anlamsal anlambilimin temel kavramını tanımlayın.
29. Operasyonel semantik ve düz anlamsal anlam hangi temel yolla
anlambilim farklıdır?
PROBLEM SETİ
1. Dil tanımlamasının iki matematiksel modeli, üretimdir.
ve tanıma. Her birinin bir programın sözdizimini nasıl tanımlayabileceğini açıklayın.
ming dili.
2. Aşağıdakiler için EBNF tanımlarını yazın:
a. Bir Java sınıfı tanımı başlık ifadesi
B. Bir Java yöntemi çağrı ifadesi
C. AC anahtarı ifadesi
D. AC birliği tanımı
e. C float değişmezleri
Vermek üzere, Örnek 3.4 BNF yeniden yazma 3. + önceliklidir * ve kuvvet +
doğru çağrışım yapmak.
4. ++ ve -- tekli operatörleri eklemek için Örnek 3.4'ün BNF'sini yeniden yazın
Java'nın.
5. Java'nın Boolean ifadelerinin bir BNF tanımını yazın.
üç operatör && , || , ve ! ve ilişkisel ifadeler.
6. Örnek 3.2'deki dilbilgisini kullanarak, bir ayrıştırma ağacı ve en soldaki
Aşağıdaki ifadelerin her biri için türetme:
a. A = A * (B + (C * A))
B. B = C * (A * C + B)
C. A = A * (B + (C))
7. Örnek 3.4'teki dilbilgisini kullanarak, bir ayrıştırma ağacı ve en soldaki
Aşağıdaki ifadelerin her biri için türetme:
a. A = ( A + B ) * C
B. A = B + C + A
C. A = A * (B + C)
D. A = B * (C * (A + B))

Sayfa 185
164
Bölüm 3 Sözdizimi ve Semantiği Tanımlama
8. Aşağıdaki dilbilgisinin belirsiz olduğunu kanıtlayın:
<S> → <A>
<A> → <A> + <A> | <id>
<id> → bir | b | C
9. Örnek 3.4'teki dilbilgisini değiştirerek bir birli eksi operatörü ekleyin.
+ veya *' dan daha yüksek önceliğe sahiptir .
10. Aşağıdaki gramer tarafından tanımlanan dili İngilizce olarak tanımlayın:
<S> → <A> <B> <C>
<A> → bir <A> | a
<B> → b <B> | B
<C> → c <C> | C
11. Aşağıdaki dilbilgisini göz önünde bulundurun:
<S> → <A> a <B> b
<A> → <A> b | B
<B> → bir <B> | a
Bu cümlenin oluşturduğu dilde aşağıdaki cümlelerden hangisi vardır?
dilbilgisi?
a. baab
B. bbbab
C. bbaaaaaa
D. bbabab
12. Aşağıdaki dilbilgisini göz önünde bulundurun:
<S> → bir <S> c <B> | <A> | B
<A> → c <A> | C
<B> → d | <A>
Bu cümlenin oluşturduğu dilde aşağıdaki cümlelerden hangisi vardır?
dilbilgisi?
a. abcd
B. acccbd
C. accccbcc
D. acd
e. acc
13. n içeren dizelerden oluşan dil için bir dilbilgisi yazın
a harfinin kopyaları ve ardından aynı sayıda kopya
b harfi, burada n > 0. Örneğin, ab, aaaabbbb ve
aaaaaaaabbbbbbbb dilde vardır ama a, abb, ba ve aaabb değildir.
14. aabb ve aaaabbbb cümleleri için ayrıştırma ağaçları çizin.
Problem 13'ün grameri.

Sayfa 186
Problem Seti 165
15. Örnek 3.1'deki BNF'yi EBNF'ye dönüştürün.
16. Örnek 3.3'ün BNF'sini EBNF'ye dönüştürün.
17. Aşağıdaki EBNF'yi BNF'ye dönüştürün:
S → A{bA}
A → a[b]A
18. İçsel nitelik ile içsel olmayan nitelik arasındaki fark nedir?
sentezlenmiş nitelik?
19. BNF temeli Örnek 3.6'daki olan bir öznitelik dilbilgisi yazın.
Bölüm 3.4.5 ancak dil kuralları aşağıdaki gibidir: Veri türleri
ifadelerde karıştırılabilir, ancak atama ifadelerinin
atama operatörünün her iki tarafında aynı tipler.
20. Temel BNF'si Örnek 3.2'deki olan bir nitelik dilbilgisi yazın ve
tür kuralları atama ifadesi örneğiyle aynı olan
Bölüm 3.4.5.
21. Bölüm 3.5.1.1'de verilen sanal makine talimatlarını kullanarak bir
Aşağıdakilerin operasyonel anlamsal tanımı:
a. Java yapmak - süre
B. Ada için
C. C++ if-then-else
D. C için
e. C anahtarı
22. Aşağıdakiler için bir düz anlamsal semantik eşleme fonksiyonu yazın
ifadeler:
a. Ada için
B. Java do-while
C. Java Boole ifadeleri
D. Java için
e. C anahtarı
23. Aşağıdaki atamaların her biri için en zayıf ön koşulu hesaplayın
ifadeler ve son koşullar:
a. a = 2 * (b - 1) - 1 {a > 0}
B. b = (c + 10) / 3 {b > 6}
C. a = a + 2 * b - 1 {a > 1}
D. x = 2 * y + x - 1 {x > 11}
24. Aşağıdaki dizilerin her biri için en zayıf ön koşulu hesaplayın
atama ifadeleri ve bunların son koşulları:
a. a = 2 * b + 1;
b = a - 3
{b < 0}

Sayfa 187
166
Bölüm 3 Sözdizimi ve Semantiği Tanımlama
B. a = 3 * (2 * b + a);
b = 2 * a - 1
{b > 5}
25. Aşağıdaki seçimlerin her biri için en zayıf ön koşulu hesaplayın
yapılar ve bunların son koşulları:
a. eğer (a == b)
b = 2 * bir + 1
Başka
b = 2 * bir;
{b > 1}
B. eğer (x < y)
x = x + 1
Başka
x = 3 * x
{x < 0}
C. Eğer (x> y)
y = 2 * x + 1
Başka
y = 3 * x - 1;
{y > 3}
26. Mantıksal bir ön testin doğruluğunu kanıtlamak için dört kriteri açıklayın
formun ilmek yapısı ise B do S ucunu
27. (n + 1) * c * n = 1 olduğunu kanıtlayın
28. Aşağıdaki programın doğru olduğunu kanıtlayın:
{n > 0}
sayı = n;
toplam = 0;
ise sayısı <> 0 do
toplam = toplam + sayı;
say = say - 1;
son
{toplam = 1 + 2 + . . . + n}

Sayfa 188
167
4.1 Giriş
4.2 Sözcük Analizi
4.3 Ayrıştırma Problemi
4.4 Özyinelemeli-İniş Ayrıştırma
4.5 Aşağıdan Yukarıya Ayrıştırma
4
Sözlüksel ve Sözdizimi
analiz

Sayfa 189
168
Bölüm 4 Sözcük ve Sözdizimi Analizi
Bir derleyici tasarımı ciddi soruşturma en azından bir dönem gerektirir
için bir derleyicinin tasarımı ve uygulanması da dahil olmak üzere yoğun bir çalışma
küçük ama gerçekçi programlama dili. Böyle bir kursun ilk kısmı
sözlük ve söz dizimi analizlerine ayrılmıştır. Sözdizimi çözümleyicisi bir derleyicinin kalbidir,
çünkü semantik analizör dahil olmak üzere diğer birçok önemli bileşen ve
ara kod oluşturucu, sözdizimi çözümleyicisinin eylemleri tarafından yönlendirilir.
Bazı okuyucular, bir derleyicinin herhangi bir bölümündeki bir bölümün neden
programlama dilleri kitabına dahil edilmiştir. için en az iki neden var
bu kitapta sözlük ve sözdizimi çözümlemelerinin bir tartışmasını dahil edin: İlk olarak, sözdizimi çözümleyicileri
doğrudan Bölüm 3'te tartışılan gramerlere dayanmaktadır, bu nedenle tartışmak doğaldır.
onları gramerlerin bir uygulaması olarak. İkincisi, sözlüksel ve sözdizimi çözümleyicilerine ihtiyaç vardır.
derleyici tasarımı dışında çok sayıda durumda. Aralarında birçok uygulama
program listeleme biçimlendiricileri, programların karmaşıklığını hesaplayan programlar ve
Bir yapılandırma dosyasının içeriğini analiz etmesi ve bunlara tepki vermesi gereken programların tümü
sözcüksel ve sözdizimsel analizler yapmak. Bu nedenle sözlük ve söz dizimi analizleri önemlidir.
hiçbir zaman bir derleyici yazmaları gerekmese bile yazılım geliştiriciler için konular. Daha öte-
dahası, bazı bilgisayar bilimi programları artık öğrencilerin bir derleyici almasını gerektirmiyor
Öğrencileri sözcük veya sözdizimi analizi konusunda talimatsız bırakan tasarım kursu.
Bu gibi durumlarda, bu bölüm programlama dili kursunda ele alınabilir. İçinde
Bir derleyici tasarım dersi gerektiren lisans programları, bu bölüm atlanabilir.
Bu bölüm, basit bir anlatımla birlikte sözcüksel çözümlemeye bir girişle başlamaktadır.
örnek. Daha sonra, iki birincil sorun da dahil olmak üzere genel ayrıştırma sorunu tartışılır.
ayrıştırma yaklaşımları ve ayrıştırmanın karmaşıklığı. Ardından, özyinelemeli-
parçalarının örnekleri de dahil olmak üzere yukarıdan aşağıya ayrıştırıcılar için iniş uygulama tekniği
özyinelemeli bir ayrıştırıcı ve birini kullanan bir ayrıştırma izi. Son bölüm tartışılıyor
aşağıdan yukarıya ayrıştırma ve LR ayrıştırma algoritması. Bu bölüm bir örnek içerir:
küçük LR ayrıştırma tablosu ve LR ayrıştırma işlemini kullanarak bir dizenin ayrıştırılması.
4.1 Giriş
Programlama dillerini uygulamaya yönelik üç farklı yaklaşım:
1. Bölüm'de tanıtılmıştır: derleme, saf yorumlama ve hibrit uygulama
mental aktivite. Derleme yaklaşımı, derleyici adı verilen bir program kullanır,
üst düzey bir programlama dilinde yazılmış programları şu dile çeviren
makine kodu. Derleme tipik olarak programlama dilini uygulamak için kullanılır.
Büyük uygulamalar için kullanılan, genellikle aşağıdaki gibi dillerde yazılan göstergeler
C++ ve COBOL. Saf yorumlama sistemleri çeviri yapmaz; yerine,
programlar bir yazılım yorumlayıcısı tarafından orijinal hallerinde yorumlanır. Saf
yorumlama genellikle yürütme verimliliğinin yüksek olduğu daha küçük sistemler için kullanılır.
HTML belgelerine gömülü komut dosyaları gibi kritik değildir.
JavaScript gibi göstergeler. Hibrit uygulama sistemleri programları çevirir
üst düzey dillerde, yorumlanan ara formlara yazılır.
Bu sistemler, büyük ölçüde
betik dillerinin popülaritesi. Geleneksel olarak, hibrit sistemler,
derleyici sistemlerden çok daha yavaş program yürütmede. Ancak, son zamanlarda

Sayfa 190
4.2 Sözcük Analizi 169
Just-in-Time (JIT) derleyicilerinin kullanımı yıllar içinde yaygınlaştı, özellikle
çoğunlukla Java programları ve Microsoft .NET sistemi için yazılmış programlar içindir.
Ara kodu makine koduna çeviren bir JIT derleyicisi kullanılır.
Yöntemler, ilk çağrıldıkları sırada. Aslında, bir JIT derleyicisi, bir
gecikmeli bir derleyici sistemine hibrit sistem.
Az önce tartışılan uygulama yaklaşımlarının üçü de hem sözlüksel hem de
ve sözdizimi çözümleyicileri.
Sözdizimi çözümleyicileri veya ayrıştırıcıları neredeyse her zaman resmi bir tanımlamaya dayanır.
programların sözdiziminin tanımı. En sık kullanılan sözdizimi açıklaması
formalizm, Bölüm 3'te tanıtılan bağlamdan bağımsız dilbilgisi veya BNF'dir.
Resmi olmayan bir sözdizimi açıklamasını kullanmak yerine BNF kullanmak, en azından
üç zorlayıcı avantaj. İlk olarak, programların sözdiziminin BNF açıklamaları
hem insanlar hem de onları kullanan yazılım sistemleri için açık ve özlüdür.
İkincisi, BNF açıklaması sözdizimi için doğrudan temel olarak kullanılabilir.
analizör. Üçüncüsü, BNF'ye dayalı uygulamaların bakımı nispeten kolaydır
modüler olmaları nedeniyle.
Hemen hemen tüm derleyiciler, sözdizimini analiz etme görevini iki ayrı gruba ayırır.
Sözcük analizi ve sözdizimi analizi olarak adlandırılan kısımlar, bu terminoloji farklı olmasına rağmen
kafa karıştırıcı. Sözcüksel çözümleyici, küçük ölçekli dil yapılarıyla ilgilenir.
adlar ve sayısal değişmezler olarak. Sözdizimi çözümleyicisi, büyük ölçekli
ifadeler, deyimler ve program birimleri gibi yapılar. Bölüm 4.2
sözcük çözümleyicilerini tanıtır. Bölüm 4.3, 4.4 ve 4.5 sözdizimi çözümleyicilerini tartışır.
Sözlüksel analizin söz diziminden ayrılmasının üç nedeni vardır.
analiz:
1. Basitlik—Sözcüksel analiz teknikleri, tekniklerinden daha az karmaşıktır.
sözdizimi analizi için gereklidir, bu nedenle sözlüksel analiz süreci basitleştirilebilir.
pler ayrı ise. Ayrıca, sözlüksel analizin alt düzey ayrıntılarını ortadan kaldırmak,
sözdizimi çözümleyiciden gelen sis, sözdizimi çözümleyiciyi hem daha küçük hem de
Daha az kompleks.
2. Verimlilik—Sözcüksel çözümleyiciyi optimize etmek faydalı olsa da, çünkü
sözcük analizi, toplam derleme süresinin önemli bir bölümünü gerektirir,
sözdizimi çözümleyicisini optimize etmek verimli değildir. Ayrılık kolaylaştırır
bu seçici optimizasyon.
3. Taşınabilirlik—Çünkü sözcük çözümleyici girdi program dosyalarını okur
ve genellikle bu girdinin arabelleğe alınmasını içerir, bu biraz platformdur
bağımlı. Ancak, sözdizimi çözümleyicisi platformdan bağımsız olabilir.
Herhangi bir yazılımın makineye bağlı parçalarını izole etmek her zaman iyidir
sistem.
4.2 Sözcük Analizi
Sözcüksel çözümleyici esasen bir kalıp eşleştiricidir. Bir model eşleştirici,
belirli bir karakter dizisiyle eşleşen belirli bir karakter dizisinin alt dizesini bulun.
kırlangıç Model eşleştirme, bilgi işlemin geleneksel bir parçasıdır. En eski kullanımlardan biri

Sayfa 191
170
Bölüm 4 Sözcük ve Sözdizimi Analizi
ed line editörü gibi metin editörleri ile desen eşleştirmesi yapıldı.
UNIX'in erken bir sürümünde tanıtıldı. O zamandan beri, desen eşleştirme bulundu
Perl ve JavaScript gibi bazı programlama dillerine girmiştir. o
Java, C++ ve C#'ın standart sınıf kitaplıkları aracılığıyla da kullanılabilir.
Sözlüksel çözümleyici, sözdizimi çözümleyicisinin ön ucu olarak işlev görür. teknik olarak
sözcük analizi, sözdizimi analizinin bir parçasıdır. Sözcüksel çözümleyici sözdizimi gerçekleştirir
program yapısının en alt seviyesinde analiz. Bir giriş programı bir
tek bir karakter dizisi olarak derleyici. Sözlüksel çözümleyici karakterleri toplar
mantıksal gruplamalara dönüştürür ve gruplamalara buna göre dahili kodlar atar.
onların yapısı. Bölüm 3'te, bu mantıksal gruplamalar sözlükler olarak adlandırılır ve
bu gruplamaların kategorileri için dahili kodlar belirteçler olarak adlandırılır . Lex-
em'ler, giriş karakter dizesini karakterle eşleştirerek tanınır
dize desenleri. Belirteçler genellikle tamsayı değerler olarak temsil edilse de,
Sözlüksel ve sözdizimi çözümleyicilerinin okunabilirliği adına, genellikle bunlara başvurulur.
adlandırılmış sabitler aracılığıyla
Aşağıdaki atama ifadesi örneğini düşünün:
sonuç = eski toplam – değer / 100;
Bu ifadenin belirteçleri ve sözlük birimleri aşağıdadır:
Sözcüksel çözümleyiciler, belirli bir girdi dizisinden sözcük birimlerini çıkarır ve
karşılık gelen jetonlar. Derleyicilerin ilk günlerinde, sözcük çözümleyicileri genellikle
tüm bir kaynak program dosyasını işledi ve bir belirteç dosyası üretti ve
sözlükler. Ancak şimdi, çoğu sözcük çözümleyicisi, konumlarını bulan alt programlardır.
girdideki bir sonraki sözlük, ilişkili simge kodunu belirleyin ve geri dönün
bunları sözdizimi çözümleyicisi olan arayana gönderir. Yani, sözcükselliğe yapılan her çağrı
analizör tek bir sözlük ve onun belirtecini döndürür. Girişin tek görünümü
Sözdizimi çözümleyicisi tarafından görülen program, sözcük çözümleyicisinin çıktısıdır, bir
bir seferde jeton.
Sözlüksel analiz süreci, yorumları ve boşlukları atlama içerir
programın anlamı ile ilgili olmadıklarından, sözlük birimlerinin dışındadır. Ayrıca,
sözcük çözümleyicisi, kullanıcı tanımlı adlar için sözcük birimlerini sembole ekler
derleyicinin sonraki aşamaları tarafından kullanılan tablo. Son olarak, sözcük çözümleyicileri
hatalı biçimlendirilmiş kayan nokta değişmezleri gibi belirteçlerdeki sözdizimsel hataları tespit eder ve
bu tür hataları kullanıcıya bildirin.
Jeton
sözlük
KİMLİK
sonuç
ASSIGN_OP
=
KİMLİK
eski toplam
SUB_OP
-
KİMLİK
değer
DIV_OP
/
INT_LIT
100
NOKTALI VİRGÜL
;

Sayfa 192
4.2 Sözcük Analizi 171
Sözlüksel bir çözümleyici oluşturmaya yönelik üç yaklaşım vardır:
1. Kullanarak dilin belirteç kalıplarının resmi bir tanımını yazın.
düzenli ifadelerle ilgili açıklayıcı bir dil. 1 Bu tanımlar-
otomatik olarak oluşturan bir yazılım aracına girdi olarak kullanılır.
sözcük çözümleyici Bunun için bu tür birçok araç mevcuttur. En yaşlı
Bunlardan lex olarak adlandırılan, genellikle UNIX sistemlerinin bir parçası olarak dahil edilir.
2. Belirteç modellerini tanımlayan bir durum geçiş diyagramı tasarlayın.
dili ve diyagramı uygulayan bir program yazınız.
3. Aşağıdakilerin belirteç modellerini tanımlayan bir durum geçiş diyagramı tasarlayın.
dili ve elle oluşturulan tabloya dayalı bir uygulamayı
durum diyagramı.
Durum geçiş diyagramı veya sadece durum diyagramı yönlendirilmiş bir grafiktir. bu
bir durum diyagramının düğümleri durum adlarıyla etiketlenir. Arklar ile etiketlenir
durumlar arasında geçişlere neden olan giriş karakterleri. Ark da olabilir
geçiş yapıldığında sözcük çözümleyicisinin gerçekleştirmesi gereken eylemleri içerir.
Sözlüksel çözümleyiciler için kullanılan formun durum diyagramları temsilidir.
sonlu otomata adı verilen bir matematik makine sınıfının . sonlu otomatlar
düzenli olarak adlandırılan bir dil sınıfının üyelerini tanımak için tasarlanabilir
diller . Normal gramerler, normal diller için üretici araçlardır.
Bir programlama dilinin belirteçleri normal bir dildir ve bir sözlükseldir.
analizör sonlu bir otomattır.
Şimdi sözlük çözümleyici yapısını bir durum diyagramı ile gösteriyoruz ve
onu uygulayan kod. Durum diyagramı basitçe durumları ve
her bir belirteç deseni için geçişler. Ancak bu yaklaşım sonuç
çok büyük ve karmaşık bir diyagramda, çünkü durum diyagramındaki her düğüm
dilin karakter kümesindeki her karakter için bir geçişe ihtiyaç duyacaktır
analiz ediliyor. Bu nedenle, onu basitleştirmenin yollarını düşünüyoruz.
Yalnızca aritmetik ifadeleri tanıyan bir sözcük çözümleyicisine ihtiyacımız olduğunu varsayalım.
değişken adları ve işlenenler olarak tamsayı değişmezleri dahil olmak üzere sions. varsayalım ki
değişken isimleri büyük harf, küçük harf ve
rakamlar ancak bir harfle başlamalıdır. İsimlerin uzunluk sınırlaması yoktur. İlk
gözlemlenmesi gereken şey, 52 farklı karakterin (herhangi bir büyük veya küçük harf) olmasıdır.
ercase harfi), bir isme başlayabilen, 52 geçiş gerektirecektir.
geçiş diyagramının ilk durumu. Ancak, bir sözcük çözümleyici ilgileniyor
sadece bir isim olduğunu ve hangi spesifik ile ilgili olmadığını belirlemede
adı olur. Bu nedenle LETTER adında bir karakter sınıfı tanımlıyoruz.
52 harfin tümü için ve herhangi bir ismin ilk harfinde tek bir geçiş kullanın.
Geçiş diyagramını basitleştirmek için başka bir fırsat,
tamsayı değişmez belirteçleri. Başlayabilecek 10 farklı karakter vardır.
tamsayı literal sözlük. Bu, başlangıç ​​durumundan 10 geçiş gerektirecektir.
durum diyagramı. Çünkü belirli rakamlar sözlüksel analojinin bir endişesi değildir.
lyzer, bir karakter tanımlarsak çok daha kompakt bir durum diyagramı oluşturabiliriz
1. Bu düzenli ifadeler, artık birçok programın parçası olan model eşleştirme tesislerinin temelidir.
programlama dilleri, doğrudan veya bir sınıf kitaplığı aracılığıyla.

Sayfa 193
172
Bölüm 4 Sözcük ve Sözdizimi Analizi
Rakamlar için DIGIT adlı sınıf ve herhangi bir karakterde tek bir geçiş kullanın
bu karakter sınıfı, tamsayı değişmezlerini toplayan bir duruma.
İsimlerimiz rakamlar içerebildiğinden, düğümden geçiş şu şekildedir:
bir ismin ilk karakterini düşürmek, LETTER veya üzerinde tek bir geçiş kullanabilir.
Bir ismin karakterlerini toplamaya devam etmek için DIGIT.
Daha sonra, içindeki ortak görevler için bazı yardımcı program alt programları tanımlıyoruz.
sözcük çözümleyici İlk olarak, getChar olarak adlandırabileceğimiz bir alt programa ihtiyacımız var.
çeşitli görevleri vardır. Çağrıldığında , getChar , girdinin sonraki karakterini alır.
giriş programı ve onu nextChar global değişkenine koyar . getChar gerekir
ayrıca giriş karakterinin karakter sınıfını belirleyin ve onu global
değişken charClass . Sözlüksel çözümleyici tarafından oluşturulan sözlük,
bir karakter dizisi veya dizi olarak uygulanabilir, lexeme olarak adlandırılır .
Biz karakteri koyma sürecini uygulamak nextChar içine
addChar adlı bir alt programdaki dize dizisi sözlüğü . Bu alt program
programlar, ihtiyaç duyan bazı karakterleri içerdiğinden açıkça çağrılmalıdır.
lexeme içine konmaz , örneğin lex- arasındaki boşluk karakterleri
emeler. Daha gerçekçi bir sözlüksel çözümleyicide, yorumlar da yerleştirilmez.
içinde lexeme .
Sözlüksel çözümleyici çağrıldığında, aşağıdaki karakterin bir sonraki karakter olması uygundur.
input sonraki sözlüğün ilk karakteridir. Bu nedenle, adlı bir işlev
getNonBlank , çözümleyici her çağrıldığında boşlukları atlamak için kullanılır.
Son olarak, belirteç kodunu hesaplamak için arama adlı bir alt programa ihtiyaç vardır.
tek karakterli belirteçler için. Örneğimizde bunlar parantezlerdir ve
aritmetik operatörler. Belirteç kodları, belirteçlere keyfi olarak atanan sayılardır.
derleyici yazar tarafından.
Şekil 4.1'deki durum diyagramı, belirteçlerimizin modellerini açıklar. o
durum diyagramının her geçişinde gerekli eylemleri içerir.
Aşağıda belirtilen bir sözcük çözümleyicisinin C uygulamasıdır:
test için bir ana sürücü işlevi de dahil olmak üzere Şekil 4.1'deki durum diyagramı
amaçlar:
/* front.c - basit için sözcüksel bir analiz sistemi
aritmetik ifadeler */
#include <stdio.h>
#include <ctype.h>
/* Genel bildirimler */
/* Değişkenler */
int karakterSınıfı ;
karakter sözlüğü [100];
char nextChar;
int lexLen;
int belirteci;
int nextToken;
DOSYA *in_fp, *fopen();

Sayfa 194
4.2 Sözcük Analizi 173
/* İşlev bildirimleri */
geçersiz addChar();
geçersiz getChar();
geçersiz getNonBlank();
int lex();
/* Karakter sınıfları */
#define HARF 0
#define BAŞKA 1
#define BİLİNMEYEN 99
/* Simge kodları */
#define INT_LIT 10
#define KİMLİK 11
#define ASSIGN_OP 20
#define ADD_OP 21
#define SUB_OP 22
#define MULT_OP 23
#define DIV_OP 24
#define LEFT_PAREN 25
#define RIGHT_PAREN 26
Şekil 4.1
için bir durum diyagramı
isimleri tanımak,
parantezler ve
aritmetik operatörler
Harf/Rakam
Mektup
Başlangıç
karakter ekle; getChar
dönüş araması ( sözlük )
Hane
dönüş Int_Lit
İD
karakter ekle; getChar
karakter ekle; getChar
Hane
karakter ekle; getChar
int
dönüş t
arama ( nextChar )
Bilinmeyen
getChar
Tamamlandı

Sayfa 195
174
Bölüm 4 Sözcük ve Sözdizimi Analizi
/******************************************************** *****/
/* ana sürücü */
ana() {
/* Girdi veri dosyasını açın ve içeriğini işleyin */
if ((in_fp = fopen("front.in", "r")) == NULL)
printf("HATA - front.in'de açılamıyor \n");
başka {
getChar();
yap {
lex();
} while (nextToken != EOF);
}
}
/******************************************************** ****/
/* arama - operatörleri ve parantezleri aramak için bir işlev
ve belirteci döndür */
int arama( char ch) {
anahtar (ch) {
durum '(':
addChar();
nextToken = LEFT_PAREN;
ara ;
durum ')':
addChar();
nextToken = RIGHT_PAREN;
ara ;
durum '+':
addChar();
nextToken = ADD_OP;
ara ;
durum '-':
addChar();
nextToken = SUB_OP;
ara ;
case '*':
addChar();
nextToken = MULT_OP;
ara ;

Sayfa 196
4.2 Sözcük Analizi 175
durum '/':
addChar();
nextToken = DIV_OP;
ara ;
varsayılan :
addChar();
nextToken = EOF;
ara ;
}
nextToken'a geri dön ;
}
/******************************************************** ****/
/* addChar - nextChar'ı sözlük birimine ekleyen bir işlev */
geçersiz addChar() {
if (lexLen <= 98) {
sözlük[lexLen++] = nextChar;
sözlük[lexLen] = 0;
}
Başka
printf("Hata - sözlük çok uzun\n");
}
/******************************************************** ****/
/* getChar - sonraki karakteri almak için bir fonksiyon
girin ve karakter sınıfını belirleyin */
geçersiz getChar() {
if ((nextChar = getc(in_fp)) != EOF) {
if (isalpha(sonraki Karakter))
charClass = HARF;
else if (isdigit(nextChar))
karakterSınıfı = SAYI;
başka charClass = BİLİNMEYEN;
}
Başka
charClass = EOF;
}
/******************************************************** ****/
/* getNonBlank - gelene kadar getChar'ı çağıran bir fonksiyon
boşluk olmayan bir karakter döndürür */
geçersiz getNonBlank() {
while (isspace(sonraki Karakter))
getChar();
}

Sayfa 197
176
Bölüm 4 Sözcük ve Sözdizimi Analizi
/
************************************************************ ***/
/* lex - aritmetik için basit bir sözlük çözümleyici
ifade */
int lex() {
lexLen = 0;
getNonBlank();
geçiş (charClass) {
/* Tanımlayıcıları ayrıştır */
vaka MEKTUBU:
addChar();
getChar();
while (charClass == HARF || charClass == DIGIT) {
addChar();
getChar();
}
nextToken = KİMLİK;
ara ;
/* Tamsayı değişmezlerini ayrıştır */
vaka BAŞARI:
addChar();
getChar();
while (charClass == DIGIT) {
addChar();
getChar();
}
nextToken = INT_LIT;
ara ;
/* Parantezler ve operatörler */
vaka BİLİNMİYOR:
arama(sonraki Karakter);
getChar();
ara ;
/* EOF */
vaka EOF:
nextToken = EOF;
sözlük[0] = 'E';
sözlük[1] = 'O';
sözlük[2] = 'F';
sözlük[3] = 0;
ara ;
} /* Anahtarın sonu */

Sayfa 198
4.3 Ayrıştırma Problemi 177
printf("Sonraki simge: %d, Sonraki sözlük %s\n",
nextToken, sözlük);
nextToken'a geri dön ;
} /* fonksiyon sonu lex */
Bu kod, sözcük çözümleyicilerinin göreli basitliğini gösterir. Tabii ki, biz
girdi arabelleğe almayı ve diğer bazı önemli ayrıntıları dışarıda bıraktılar. Daha öte-
dahası, çok küçük ve basit bir giriş dili ile ilgilendik.
Aşağıdaki ifadeyi göz önünde bulundurun:
(toplam + 47) / toplam
Bunun üzerinde kullanıldığında front.c'nin sözlüksel çözümleyicisinin çıktısı aşağıdadır .
ifade:
Sonraki simge: 25 Sonraki sözlük (
Sonraki simge: 11 Sonraki sözlük toplamıdır
Sonraki simge: 21 Sonraki sözlük +
Sonraki simge: 10 Sonraki sözlük 47'dir
Sonraki simge: 26 Sonraki sözlük )
Sonraki simge: 24 Sonraki sözcük birimi /
Sonraki simge: 11 Sonraki sözlük toplamdır
Sonraki simge: -1 Sonraki sözcük grubu EOF'dir
Programlardaki isimler ve ayrılmış kelimeler benzer kalıplara sahiptir. Olmasına rağmen
her özel ayrılmış kelimeyi tanımak için bir durum diyagramı oluşturmak mümkün
programlama dili, bu aşırı derecede büyük bir durum diyagramına neden olur.
Sözlüksel çözümleyicinin adları tanımasını sağlamak çok daha basit ve hızlıdır.
aynı kalıba sahip ayrılmış kelimeler ve ayrılmış bir tabloda bir arama kullanın
hangi isimlerin ayrılmış kelimeler olduğunu belirlemek için kelimeler. Bu yaklaşımı kullanarak
yandaşlar, sözcükleri ad belirteci kategorisinde istisna olarak ayırdı.
Sözcüksel bir çözümleyici, genellikle metnin ilk yapısından sorumludur.
derleyici için bir ad veritabanı görevi gören sembol tablosu. girişler
sembol tablosunda, kullanıcı tanımlı adlarla ilgili bilgilerin yanı sıra
isimlerin özellikleri. Örneğin, isim bir değişkenin ismiyse, değişken
mümkün'ün türü, simge tablosunda saklanacak niteliklerinden biridir. İsimler
genellikle sözlük çözümleyici tarafından sembol tablosuna yerleştirilir. özellikleri
bir isim genellikle sembol tablosuna derleyicinin bir kısmı tarafından konur.
sözcük çözümleyicisinin eylemlerinden sonra.
4.3 Ayrıştırma Problemi
Sözdizimi analizi olarak adlandırılan sözdizimi analiz sürecinin parçası
genellikle ayrıştırma olarak adlandırılır . Bu ikisini birbirinin yerine kullanacağız.
Bu bölümde genel ayrıştırma sorunu tartışılmakta ve iki sorun tanıtılmaktadır.
ayrıştırma algoritmalarının ana kategorileri, yukarıdan aşağıya ve aşağıdan yukarıya ve ayrıca
ayrıştırma işleminin karmaşıklığı.

Sayfa 199
178
Bölüm 4 Sözcük ve Sözdizimi Analizi
4.3.1 Ayrıştırmaya Giriş
Programlama dilleri için ayrıştırıcılar, verilen programlar için ayrıştırma ağaçları oluşturur.
Bazı durumlarda, ayrıştırma ağacı yalnızca örtük olarak oluşturulur, yani per-
muhtemelen ağacın yalnızca bir geçişi oluşturulur. Ama her durumda, bilgi
ayrıştırma ağacını oluşturmak için gerekli ayrıştırma sırasında oluşturulur. Her iki ayrıştırma ağacı
ve türevler, bir dilin ihtiyaç duyduğu tüm sözdizimsel bilgileri içerir.
işlemci.
Sözdizimi analizinin iki farklı amacı vardır: Birincisi, sözdizimi çözümleyici
sözdizimsel olarak doğru olup olmadığını belirlemek için giriş programını kontrol etmelidir.
Bir hata bulunduğunda, analiz cihazı bir teşhis mesajı üretmeli ve
kurtarmak. Bu durumda, kurtarma, normal bir duruma geri dönmesi gerektiği anlamına gelir ve
giriş programı analizine devam edin. Bu adım gereklidir, böylece
derleyici, girdinin tek bir analizi sırasında mümkün olduğunca çok hata bulur
programı. İyi yapılmazsa, hata kurtarma daha fazla hataya neden olabilir veya
en az daha fazla hata mesajı. Sözdizimi analizinin ikinci amacı, bir
ayrıştırma ağacını tamamlayın veya en azından tam ayrıştırma ağacının yapısını izleyin,
sözdizimsel olarak doğru giriş için. Ayrıştırma ağacı (veya izi) temel olarak kullanılır
çeviri için.
Ayrıştırıcılar, ayrıştırma oluşturdukları yöne göre kategorilere ayrılır
ağaçlar. Ağacın oluşturulduğu iki geniş ayrıştırıcı sınıfı yukarıdan aşağıyadır.
kökten aşağıya yapraklara ve aşağıdan yukarıya , ayrıştırma ağacının
yapraklardan köke doğru yapılır.
Bu bölümde, dilbilgisi için küçük bir dizi notasyon kuralı kullanıyoruz.
tartışmayı daha az karmaşık hale getirmek için semboller ve dizeler. Resmi diller için,
bunlar aşağıdaki gibidir:
1. Terminal sembolleri—alfabenin başındaki küçük harfler
(a, b, . . .)
2. Terminal olmayan semboller—alfanın başındaki büyük harfler-
bahis (A, B, . . .)
3. Terminaller veya terminal olmayanlar—alfabenin sonundaki büyük harfler
(G, X, Y, Z)
4. Uç dizileri—alfabenin sonundaki küçük harfler (w, x,
y, z)
5. Karışık diziler (uçlar ve/veya uçlar olmayanlar)—küçük Yunanca harfler
(, , , )
Programlama dilleri için terminal sembolleri küçük ölçekli sözdizimleridir.
dilin tik yapıları, bizim sözlük olarak adlandırdığımız şeyler. bu
programlama dillerinin terminal olmayan sembolleri genellikle çağrışımsaldır
adlar veya kısaltmalar, köşeli parantezler içinde, örneğin,
<while_statement>, <expr> ve <function_def>. Bir lan-
guage (programlar, bir programlama dili durumunda)
terminaller. Karışık dizeler, dilbilgisi kurallarının sağ taraflarını (RHS'ler) tanımlar
ve ayrıştırma algoritmalarında kullanılır.

Sayfa 200
4.3 Ayrıştırma Problemi 179
4.3.2 Yukarıdan Aşağıya Ayrıştırıcılar
Yukarıdan aşağıya bir ayrıştırıcı, ön siparişte bir ayrıştırma ağacını izler veya oluşturur. Ön sipariş geçişi
bir ayrıştırma ağacının kökü ile başlar. Her düğüm, dalları bulunmadan önce ziyaret edilir.
takip etti. Belirli bir düğümden gelen dallar soldan sağa sırayla izlenir.
Bu, en soldaki türetmeye karşılık gelir.
Türetme açısından, yukarıdan aşağıya bir ayrıştırıcı aşağıdaki gibi tanımlanabilir:
En soldaki türetmenin parçası olan bir cümlesel form verildiğinde, ayrıştırıcının görevi
bu en soldaki türetmedeki bir sonraki cümle biçimini bulmak için. genel form
sol cümlesel formun xA'dır, burada bizim gösterim kurallarımız x bir dizgedir
A terminali olmayan ve karma bir dizedir. çünkü x
yalnızca terminalleri içerir, A cümle biçiminde en soldaki terminal olmayandır,
bu yüzden soldaki bir sonraki cümlesel formu elde etmek için genişletilmesi gereken budur.
en türetme. Bir sonraki cümle biçimini belirlemek, bir seçim meselesidir.
LHS'si A olan doğru dilbilgisi kuralı. Örneğin, eğer mevcut
cümle formu
xA
ve A-kuralları A → bB, A → cBb ve A → a'dır, yukarıdan aşağıya bir ayrıştırıcı
bir sonraki cümle biçimini elde etmek için bu üç kuraldan birini seçin.
xbB, xcBb veya xa olsun. Bu, yukarıdan aşağıya için ayrıştırma karar problemidir.
ayrıştırıcılar.
Farklı yukarıdan aşağıya ayrıştırma algoritmaları, farklı bilgiler kullanır.
ayrıştırma kararları En yaygın yukarıdan aşağıya ayrıştırıcılar doğru olanı seçer
Geçerli cümle biçiminde en soldaki terminal olmayan için RHS, com-
bir sonraki giriş belirtecini üretilebilecek ilk sembollerle eşleştirme
bu kuralların RHS'leri tarafından. Hangi RHS'nin sol ucunda bu jeton varsa
ürettiği dizenin doğru olanıdır. Böylece, xA cümle biçiminde,
ayrıştırıcı, A tarafından oluşturulan ilk belirteç ne olursa olsun kullanırdı.
sonraki cümle formunu elde etmek için hangi A-kuralının kullanılması gerektiğini belirleyin. İçinde
yukarıdaki örnekte, A kurallarının üç RHS'sinin tümü farklı ile başlar
terminal sembolleri. Ayrıştırıcı, aşağıdakilere dayalı olarak doğru RHS'yi kolayca seçebilir:
bu örnekte a, b veya c olması gereken bir sonraki girdi belirteci. Genel olarak,
doğru RHS'yi seçmek o kadar kolay değildir, çünkü bazı
Geçerli cümle biçimindeki en soldaki terminal olmayanın RHS'leri başlayabilir
bir terminal dışı ile.
En yaygın yukarıdan aşağıya ayrıştırma algoritmaları yakından ilişkilidir.
Bir özyinelemeli-iniş ayrıştırıcı bir sözdizimi analizörü kodlanmış versiyonu dayanır
doğrudan dilin sözdiziminin BNF açıklaması üzerinde. en kom-
özyinelemeli inişe alternatif, bir ayrıştırma tablosu kullanmaktır.
kodu, BNF kurallarını uygulamak için. Bunların her ikisi de LL algo-
ritmler eşit derecede güçlüdür, yani hepsinin aynı alt kümesinde çalışırlar.
bağlamdan bağımsız gramerler. LL'deki ilk L, soldan sağa taramayı belirtir.
girdi; ikinci L, en soldaki türevin üretildiğini belirtir.
Bölüm 4.4, bir uygulama için özyinelemeli iniş yaklaşımını tanıtmaktadır.
LL ayrıştırıcı.

Sayfa 201
180
Bölüm 4 Sözcük ve Sözdizimi Analizi
4.3.3 Aşağıdan Yukarıya Ayrıştırıcılar
Aşağıdan yukarıya bir ayrıştırıcı, yapraklardan başlayarak bir ayrıştırma ağacı oluşturur ve
köke doğru ilerliyor. Bu ayrıştırma sırası, bir
en sağdaki türetme. Yani, türetmenin cümlesel biçimleri pro-
sondan birinciye doğru sıralanmıştır. Türetme açısından, aşağıdan yukarıya bir ayrıştırıcı
aşağıdaki gibi tanımlanabilir: Doğru bir cümle formu verildiğinde, 2 ayrıştırıcı
olması gereken dilbilgisinde kuralın RHS'sinin hangi alt dizesi olduğunu belirleyin.
en sağdaki önceki cümle biçimini üretmek için LHS'sine indirgenebilir
türetme. Örneğin, aşağıdan yukarıya ayrıştırıcı için ilk adım,
İlk verilen cümlenin hangi alt dizisi, kendisine indirgenecek olan RHS'dir.
türetmede ikinci son cümle formunu almak için karşılık gelen LHS.
Azaltmak için doğru RHS'yi bulma süreci,
belirli bir doğru cümle formunun, aşağıdakilerden birden fazla RHS içerebileceğini
ayrıştırılan dilin grameri. Doğru RHS denir
işlemek .
Aşağıdaki dilbilgisini ve türetmeyi göz önünde bulundurun:
S → aAc
A → aA b
S => aAc => aaAc => aabc
Bu cümlenin aşağıdan yukarıya ayrıştırıcısı olan aabc, cümle ile başlar ve
içindeki kolu bulun. Bu örnekte, bu kolay bir iştir, çünkü dize şunları içerir:
sadece bir RHS, b. Ayrıştırıcı b'yi LHS, A ile değiştirdiğinde, sec-
türetmedeki son cümle biçimine, aaAc. Genel durumda, belirtildiği gibi
önceden, tutamacı bulmak çok daha zordu, çünkü bir cümle biçimi
birkaç farklı RHS içerebilir.
Aşağıdan yukarıya bir ayrıştırıcı, belirli bir doğru cümlesel formun tutamağını şu şekilde bulur:
olası bir tutamağın bir veya iki tarafındaki sembolleri incelemek. için semboller
olası tanıtıcının sağ tarafı genellikle girişte olmayan belirteçlerdir.
henüz analiz edilmiştir.
En yaygın aşağıdan yukarıya ayrıştırma algoritmaları LR ailesindedir,
burada L, girişin soldan sağa taramasını belirtir ve R, bir
en sağdaki türetme oluşturulur.
4.3.4 Ayrıştırmanın Karmaşıklığı
Herhangi bir açık dilbilgisi için çalışan ayrıştırma algoritmaları karmaşıktır
ve verimsiz. Aslında, bu tür algoritmaların karmaşıklığı O(n 3 ), yani
aldıkları süre, uzunluk küpünün sırasına göredir.
ayrıştırılacak dize. Bu nispeten büyük miktarda zaman gereklidir, çünkü
bu algoritmalar sıklıkla cümlenin bir kısmını yedeklemeli ve yeniden ayrıştırmalıdır.
analiz ediliyor. Ayrıştırıcı bir hata yaptığında yeniden ayrıştırma gereklidir.
2. Doğru cümle biçimi, en sağdaki türetmede görünen bir cümle biçimidir.

Sayfa 202
4.4 Özyinelemeli-Descent Ayrıştırma 181
ayrıştırma işlemi. Ayrıştırıcıyı yedeklemek, ayrıştırmanın o kısmını da gerektirir.
inşa edilmekte olan ağaç (veya izi) sökülmeli ve yeniden yapılmalıdır. O(n 3 ) algo-
Ritimler normalde, sözdizimi analizi gibi pratik süreçler için kullanışlı değildir.
bir derleyici, çünkü çok yavaşlar. Bu gibi durumlarda bilgisayar
bilim adamları genellikle daha az genel olsa da daha hızlı algoritmalar ararlar. gen-
erality, verimlilik için takas edilir. Ayrıştırma açısından, daha hızlı algoritmalar
tüm olası dilbilgisi kümesinin yalnızca bir alt kümesi için çalıştığını buldu. Bunlar
alt küme, tanımlayan dilbilgilerini içerdiği sürece algoritmalar kabul edilebilir.
Programlama dilleri. (Aslında, Bölüm 3'te tartışıldığı gibi, tüm sınıf
bağlamdan bağımsız gramerlerin çoğu, çoğu dilin tüm sözdizimini tanımlamak için yeterli değildir.
Programlama dilleri.)
Ticari derleyicilerin sözdizimi çözümleyicileri için kullanılan tüm algoritmalar
karmaşıklığa sahip O(n), bu da aldıkları sürenin doğrusal olarak ilişkili olduğu anlamına gelir.
ayrıştırılacak dizenin uzunluğu. Bu, O(n 3 ) işlevinden çok daha verimlidir.
algoritmalar.
4.4 Özyinelemeli-İniş Ayrıştırma
Bu bölüm özyinelemeli inişli yukarıdan aşağıya ayrıştırıcı uygulamasını tanıtır.
işlem süreci.
4.4.1 Özyinelemeli-İniş Ayrıştırma Süreci
Bir özyinelemeli iniş ayrıştırıcı, bir koleksiyondan oluştuğu için bu şekilde adlandırılmıştır.
çoğu özyinelemeli olan alt programlar ve bir ayrıştırma ağacı üretir.
yukarıdan aşağıya sıra. Bu özyineleme, programlamanın doğasının bir yansımasıdır.
birkaç farklı türde iç içe yapı içeren diller. İçin
örneğin, ifadeler genellikle diğer ifadelerde iç içedir. Ayrıca parantez içindeki
ifadeler uygun şekilde iç içe olmalıdır. Bu yapıların sözdizimi doğal olarak
özyinelemeli dilbilgisi kuralları ile açıklanmıştır.
EBNF, özyinelemeli iniş ayrıştırıcıları için idealdir. Bölümden Hatırlatma
3, birincil EBNF uzantılarının, ne olduklarını belirten parantezler olduğunu
enclose sıfır veya daha fazla kez görünebilir ve ne olduğunu belirten parantezler
bir kez görünebilir veya hiç görünmeyebilirler. Her iki durumda da ekteki
semboller isteğe bağlıdır. Aşağıdaki örnekleri göz önünde bulundurun:
<if_statement> → if <logic_expr> <ifade> [ başka <ifade>]
<ident_list> → ident { , ident}
İlk kuralda, if ifadesinin else yan tümcesi isteğe bağlıdır. Saniyede,
<ident_list> bir tanımlayıcıdır, ardından virgül sıfır veya daha fazla tekrarlanır
ve bir tanımlayıcı.
Özyinelemeli inişli bir ayrıştırıcı, kendi içindeki her terminal olmayan için bir alt programa sahiptir.
ilgili gramer İlgili alt programın sorumluluğu
belirli bir nonterminal aşağıdaki gibidir: Bir girdi dizesi verildiğinde,

Sayfa 203
182
Bölüm 4 Sözcük ve Sözdizimi Analizi
o terminal olmayanda köklenebilen ve yaprakları olan ayrıştırma ağacından
giriş dizesiyle eşleştirin. Gerçekte, özyinelemeli inişli bir ayrıştırma alt programı
ilişkili olduğu dil (dizeler kümesi) için bir ayrıştırıcı
terminal dışı.
Basit aritmetik ifadelerin aşağıdaki EBNF tanımını göz önünde bulundurun:
<ifade> → <terim> {( + | - ) <terim>}
<terim> → <faktör> {( * | / ) <faktör>}
<faktör> → kimlik | int_constant | ( <ifade> )
Bölüm 3'ten, aritmetik ifadeler için bir EBNF dilbilgisinin, örneğin
bunun gibi, herhangi bir çağrışım kuralı zorlamaz. Bu nedenle, böyle bir araç kullanırken
Bir derleyicinin temeli olarak dilbilgisi, kodun
Normalde sözdizimi analizi tarafından yönlendirilen üretim süreci, kod üretir
dilin çağrışım kurallarına uyar. Bu kolayca yapılabilir
özyinelemeli iniş ayrıştırma kullanıldığında.
Aşağıdaki özyinelemeli iniş işlevinde, ifade , sözcük çözümleyici
Bölüm 4.2'de uygulanan fonksiyon. Bir sonraki sözlüğü alır ve koyar
global değişken nextToken içindeki belirteç kodu . Token kodları tanımlanır
Adlandırılmış sabitler olarak, Bölüm 4.2'de olduğu gibi.
Tek bir RHS'ye sahip bir kural için özyinelemeli bir iniş alt programı nispeten
basit. RHS'deki her bir terminal sembolü için, bu terminal sembolü
nextToken ile eşleştirildi . Eşleşmiyorlarsa, bu bir sözdizimi hatasıdır. Eşleşirlerse,
sözcük çözümleyici bir sonraki giriş belirtecini almak için çağrılır. Her bir terminal dışı için,
bu terminal olmayan için ayrıştırma alt programı çağrılır.
Önceki sınavdaki ilk kural için özyinelemeli iniş alt programı-
C ile yazılmış ple dilbilgisi,
/* ifade
Kural tarafından oluşturulan dilde dizeleri ayrıştırır:
<ifade> -> <terim> {(+ | -) <terim>}
*/
geçersiz ifade() {
printf("<ifade>\n girin");
/* İlk terimi ayrıştır */
Terim();
/* Bir sonraki simge + veya - olduğu sürece, şunu al
sonraki belirteci ve sonraki terimi ayrıştırın */
while (nextToken == ADD_OP || nextToken == SUB_OP) {
lex();
Terim();
}
printf("Çıkış <ifade>\n");
} /* Fonksiyon sonu ifadesi */

Sayfa 204
4.4 Özyinelemeli-Descent Ayrıştırma 183
ifade işlevinin izleme çıktı ifadelerini içerdiğine dikkat edin.
Bu bölümde daha sonra gösterilen örnek çıktıyı üretmek için dahil edilmiştir.
Özyinelemeli-inişli ayrıştırma alt programları, kuralla yazılır
her birinin nextToken içindeki bir sonraki girdi belirtecini bıraktığını . Yani, ne zaman
bir ayrıştırma işlevi başlar, nextToken'ın aşağıdaki koda sahip olduğunu varsayar .
ayrıştırma işleminde henüz kullanılmayan girdinin en soldaki simgesi.
Dilin ifade işlevinin ayrıştırdığı kısmı bir veya
artı veya eksi operatörleriyle ayrılmış daha fazla terim. bu dil
terminal olmayan <expr> tarafından oluşturulur. Bu nedenle, önce işlevi çağırır
bu terimleri ayrıştırır ( terim ). Daha sonra bu işlevi, olduğu sürece çağırmaya devam eder.
ADD_OP veya SUB_OP belirteçlerini bulur ( lex çağırarak geçer ). Bu
özyinelemeli iniş işlevi çoğundan daha basittir, çünkü ilişkili kuralı
sadece bir RHS'ye sahiptir. Ayrıca, sözdizimi hatası için herhangi bir kod içermez
algılama veya kurtarma, çünkü bunlarla ilişkili algılanabilir bir hata yoktur.
gramer kuralı.
Kuralı olan bir terminal olmayan için özyinelemeli inişli ayrıştırma alt programı
birden fazla RHS, hangi RHS'nin ayrıştırılacağını belirlemek için kodla başlar.
Her bir RHS (derleyici yapım zamanında) incelenerek aşağıdakiler kümesi belirlenir:
Cümlelerin başında görünebilen terminal sembolleri üretebilir.
Bu kümeleri bir sonraki giriş belirteciyle eşleştirerek, ayrıştırıcı şunları seçebilir:
doğru RHS.
<term> için ayrıştırma alt programı, <expr> için olana benzer:
/* Terim
Kural tarafından oluşturulan dilde dizeleri ayrıştırır:
<term> -> <faktör> {(* | /) <faktör>)
*/
geçersiz terim() {
printf("<terim>\n girin");
/* İlk faktörü ayrıştır */
faktör();
/* Bir sonraki simge * veya / olduğu sürece,
sonraki belirteci ve sonraki faktörü ayrıştırın */
while (nextToken == MULT_OP || nextToken == DIV_OP) {
lex();
faktör();
}
printf("Çıkış <term>\n");
} /* Fonksiyon terimi sonu */
Aritmetik ifademizin terminal olmayan <faktörü> işlevi
dilbilgisi, iki RHS'si arasında seçim yapmalıdır. Ayrıca hata algılamayı da içerir.
<faktör> işlevinde, bir sözdizimi hatası algılamaya verilen tepki basitçe
hata işlevini çağırmak için . Gerçek bir ayrıştırıcıda, bir teşhis mesajı olmalıdır

Sayfa 205
184
Bölüm 4 Sözcük ve Sözdizimi Analizi
bir hata algılandığında üretilir. Ayrıca, ayrıştırıcılar kurtarılmalıdır
ayrıştırma işleminin devam edebilmesi için hata.
/* faktör
Kural tarafından oluşturulan dilde dizeleri ayrıştırır:
<faktör> -> kimlik | int_constant | ( <ifade )
*/
geçersiz faktör() {
printf("<faktör> girin\n");
/* Hangi RHS'yi belirle */
if (nextToken == IDENT || nextToken == INT_LIT)
/* Sonraki jetonu al */
lex();
/* RHS ( <expr>) ise, lex'i arayın
sol parantez, ifadeyi arayın ve sağı kontrol edin
parantez */
başka {
if (nextToken == LEFT_PAREN) {
lex();
ifade();
if (nextToken == RIGHT_PAREN)
lex();
Başka
hata();
} /* if sonu (nextToken == ... */
/* Bir id, bir tamsayı değişmezi veya bir sol değildi
parantez */
Başka
hata();
} /* Başkasının sonu */
printf("Çıkış <faktör>\n");
} /* Fonksiyon faktörü sonu */
Örnek ifadenin ayrıştırılmasının izi aşağıdadır (toplam + 47) /
total , ayrıştırma işlevlerini kullanarak ifade , terim ve faktör ve işlev
Bölüm 4.2'den lex . Ayrıştırmanın lex ve start öğesini çağırarak başladığını unutmayın.
sembol rutini, bu durumda, ifade .
Sonraki simge: 25 Sonraki sözlük (
<ifade> girin
<term> girin
<faktör> girin

Sayfa 206
4.4 Özyinelemeli-Descent Ayrıştırma 185
Şekil 4.2
Ayrıştırma ağacı
(toplam + 47) / toplam
toplam
Toplam
(
)
/
47
<faktör>
<dönem>
<ifade>
<faktör>
<dönem>
<ifade>
+
<dönem>
<faktör>
<faktör>
Sonraki simge: 11 Sonraki sözlük toplamıdır
<ifade> girin
<term> girin
<faktör> girin
Sonraki simge: 21 Sonraki sözlük +
<faktör>'den çık
<term>'den çık
Sonraki simge: 10 Sonraki sözlük 47'dir
<term> girin
<faktör> girin
Sonraki simge: 26 Sonraki sözlük )
<faktör>'den çık
<term>'den çık
<expr>'den çık
Sonraki simge: 24 Sonraki sözcük birimi /
<faktör>'den çık
Sonraki simge: 11 Sonraki sözlük toplamdır
<faktör> girin
Sonraki simge: -1 Sonraki sözcük grubu EOF'dir
<faktör>'den çık
<term>'den çık
<expr>'den çık
Önceki ifade için ayrıştırıcı tarafından izlenen ayrıştırma ağacı,
Şekil 4.2.

Sayfa 207
186
Bölüm 4 Sözcük ve Sözdizimi Analizi
Bir örnek dilbilgisi kuralı ve ayrıştırma işlevi, katılaşmaya yardımcı olmalıdır
okuyucunun özyinelemeli iniş ayrıştırma anlayışı. Aşağıdaki bir gram-
Java if ifadesinin matematiksel açıklaması :
<ifstmt> → if (<boolexpr>) <ifade> [ başka <ifade>]
Bu kural için özyinelemeli iniş alt programı aşağıdaki gibidir:
/* ifstmt işlevi
Kural tarafından oluşturulan dilde dizeleri ayrıştırır:
<ifstmt> -> if (<boolexpr>) <ifade>
[başka <ifade>]
*/
geçersiz ifstmt() {
/* İlk belirtecin 'if' olduğundan emin olun */
if (nextToken != IF_CODE)
hata();
başka {
/* Bir sonraki simgeye ulaşmak için lex'i arayın */
lex();
/* Sol parantez için kontrol edin */
if (nextToken != LEFT_PAREN)
hata();
başka {
/* Boole ifadesini ayrıştırmak için boolexpr'i çağırın */
boolexpr();
/* Sağdaki parantezi kontrol edin */
if (nextToken != RIGHT_PAREN)
hata();
başka {
/* then cümlesini ayrıştırmak için çağrı ifadesi */
Beyan();
/* Sırada else varsa, else yan tümcesini ayrıştırın */
if (nextToken == ELSE_CODE) {
/* Diğerlerini unutmak için lex'i ara */
lex();
Beyan();
} /* if sonu (nextToken == ELSE_CODE ... */
} /* if öğesinin sonu (nextToken != RIGHT ... */
} /* if öğesinin sonu (nextToken != LEFT ... */
} /* if öğesinin sonu (nextToken != IF_CODE ... */
} /* ifstmt'nin sonu */
Bu işlevin ifadeler için ayrıştırıcı işlevleri ve Boolean kullandığına dikkat edin.
Bu bölümde verilmeyen ifadeler.
Bu örneklerin amacı, sizi özyinelemeli bir iniş olduğuna ikna etmektir.
için uygun bir dilbilgisi varsa ayrıştırıcı kolayca yazılabilir.

Sayfa 208
4.4 Özyinelemeli-Descent Ayrıştırma 187
dilim. Özyinelemeli bir inişe izin veren bir dilbilgisinin özellikleri
oluşturulacak ayrıştırıcı aşağıdaki alt bölümde tartışılmaktadır.
4.4.2 LL Dilbilgisi Sınıfı
Bir derleyici için ayrıştırma stratejisi olarak özyinelemeli inişi kullanmayı seçmeden önce veya
başka bir program analiz aracı, yaklaşımın sınırlamaları göz önünde bulundurulmalıdır,
dilbilgisi kısıtlamaları açısından. Bu bölümde bu kısıtlamalar ve
onların olası çözümleri.
için feci bir soruna neden olan basit bir dilbilgisi özelliği
LL ayrıştırıcıları özyineleme bırakılmıştır. Örneğin, aşağıdaki kuralı göz önünde bulundurun:
A → A + B
A için özyinelemeli iniş ayrıştırıcı alt programı hemen ayrıştırmak için kendisini çağırır
RHS'sindeki ilk sembol. A ayrıştırıcı alt programının bu aktivasyonu daha sonra
hemen kendini tekrar çağırır, tekrar vesaire. Bunu görmek kolaydır
hiçbir yere götürmez (yığın taşması dışında).
A → A + B kuralındaki sol özyinelemeye doğrudan sol özyineleme denir ,
çünkü tek bir kuralda gerçekleşir. Doğrudan sol özyineleme, bir
aşağıdaki süreçle dilbilgisi:
Her terminal olmayan için, A,
1. A kurallarını A → A 1 , c A m olarak gruplandırın
1
2
C
n
>s'nin hiçbiri A ile başlamaz
2. Orijinal A-kurallarını şununla değiştirin:
A → 1 A 2 A c
n bir
A → 1 A 2 A m A
Boş dizeyi belirttiğine dikkat edin. RHS'si olan bir kurala
silme kuralı , çünkü bir türevde kullanımı LHS'sini etkin bir şekilde siler.
cümle formu.
Aşağıdaki örnek dilbilgisini ve uygulamanın uygulamasını göz önünde bulundurun.
yukarıdaki süreç:
E → E + TT
T → T * FF
F → (E) kimliği
E-kuralları için 1 = + T ve = T'ye sahibiz, bu nedenle E-kurallarını şu şekilde değiştiririz:
E → TE
E → + TE
T-kuralları için 1 = * F ve = F'ye sahibiz, dolayısıyla T-kurallarını şununla değiştiriyoruz:
T → FT
T → * FT

Sayfa 209
188
Bölüm 4 Sözcük ve Sözdizimi Analizi
F-kurallarında sol özyineleme olmadığından, aynı kalırlar, dolayısıyla
tam değiştirme dilbilgisi
E → TE
E → + TE
T → FT
T → * FT
F → (E) kimliği
Bu dilbilgisi, orijinal dilbilgisi ile aynı dili oluşturur, ancak
sol özyinelemeli.
EBNF kullanılarak yazılan dilbilgisi ifadesinde olduğu gibi
Bölüm 4.4.1, bu dilbilgisi, operatörlerin sol birliğini belirtmez.
Ancak, buna dayalı olarak kod üretimini tasarlamak nispeten kolaydır.
dilbilgisi, böylece toplama ve çarpma operatörleri bırakılmış olacak
çağrışım.
Dolaylı sol özyineleme, doğrudan sol özyineleme ile aynı sorunu ortaya çıkarır. İçin
örneğin, sahip olduğumuzu varsayalım
A → B bir A
B → Bir b
Bu kurallar için özyinelemeli bir iniş ayrıştırıcısı, A alt program imme-
doğrudan A alt programını çağıran B için alt programı çağırın.
Bu nedenle, sorun doğrudan sol özyineleme ile aynıdır. soldaki sorun
özyineleme, üst yapı oluşturmaya yönelik özyinelemeli iniş yaklaşımıyla sınırlı değildir.
aşağı ayrıştırıcılar. Tüm yukarıdan aşağıya ayrıştırma algoritmaları için bir sorundur. Neyse ki,
sol özyineleme, aşağıdan yukarıya ayrıştırma algoritmaları için bir sorun değildir.
Dolaylı sola kaldırmak için belirli bir dilbilgisini değiştirmek için bir algoritma var
özyineleme (Aho ve diğerleri, 2006), ancak burada kapsanmamaktadır. Gram yazarken
bir programlama dili için mar, genellikle sol yinelemeyi dahil etmekten kaçınılabilir.
Hem doğrudan hem de dolaylı olarak.
Sol özyineleme, yukarıdan aşağıya ayrıştırmaya izin vermeyen tek dilbilgisi özelliği değildir.
ing. Bir diğeri, ayrıştırıcının her zaman doğru RHS'yi seçip seçemeyeceğidir.
tarafından üretilen ilk belirteci kullanarak, bir sonraki girdi belirtecinin temeli
geçerli cümle biçiminde en soldaki nonterminal. nispeten basit bir
Bunun yapılıp yapılamayacağını gösteren sol olmayan özyinelemeli bir dilbilgisi testi,
ikili ayrıklık testi denir . Bu test hesaplama yeteneği gerektirir
bir dilbilgisinde belirli bir terminal olmayan sembolün RHS'lerine dayalı bir küme. Bunlar
İLK olarak adlandırılan kümeler şu şekilde tanımlanır:
FIRST() = {a => * a} (Eğer => * , FIRST() içinde ise)
burada =>*, 0 veya daha fazla türetme adımı anlamına gelir.
Herhangi bir karışık dize için İLK'i hesaplayacak bir algoritma şurada bulunabilir:
Aho et al. (2006). Bizim amaçlarımız için, FIRST genellikle teftiş ile hesaplanabilir.
gramer bilgisi.

Sayfa 210
4.4 Özyinelemeli-Descent Ayrıştırma 189
İkili ayrıklık testi aşağıdaki gibidir:
Birden fazla RHS'ye sahip dilbilgisinde her bir terminal olmayan A için,
A → i ve A → j her bir kural çifti için , şu doğru olmalıdır:
İLK( i ) x İLK( j ) =
(İki kümenin kesişimi, FIRST( i ) ve FIRST( j ) olmalıdır.
boş.)
Başka bir deyişle, bir terminal olmayan A'nın birden fazla RHS'si varsa, ilk terminal
her biri için bir türevde üretilebilecek bir sembol,
bu RHS'ye özgüdür. Aşağıdaki kuralları göz önünde bulundurun:
A → aB bAb Bb
B → cB d
A-kurallarının RHS'leri için İLK kümeler {a}, {b} ve {c, d}'dir;
açıkça ayrıktırlar. Bu nedenle, bu kurallar ikili ayrıklık testini geçer.
Bunun özyinelemeli iniş ayrıştırıcısı açısından anlamı, şudur:
terminal olmayan A'yı ayrıştırmak için alt program, hangi RHS ile ilgilendiğini seçebilir
yalnızca oluşturulan girişin (belirteç) ilk terminal sembolünü görerek
terminal dışı tarafından. Şimdi kuralları düşün
A → aB BAb
B → aB b
A-kurallarındaki RHS'ler için İLK kümeler {a} ve {a, b}'dir, bunlar açıkça
ayrık. Dolayısıyla, bu kurallar ikili ayrıklık testinde başarısız olur. Ayrıştırıcı açısından,
A için alt program, aşağıdakilere bakarak hangi RHS'nin ayrıştırıldığını belirleyemedi.
girdinin bir sonraki sembolü, çünkü eğer bir a olsaydı, RHS olabilir. Bu konu
bir veya daha fazla RHS'nin terminal olmayanlarla başlaması elbette daha karmaşıktır.
Çoğu durumda, ikili ayrıklık testinde başarısız olan bir dilbilgisi,
Testi geçecek şekilde değiştirildi. Örneğin, kuralı düşünün
<değişken> → tanımlayıcı tanımlayıcı [<ifade>]
Bu, bir <değişken> öğesinin bir tanımlayıcı veya ardından gelen bir tanımlayıcı olduğunu belirtir.
parantez içinde bir ifade (bir alt simge). Bu kurallar açıkça çifti geçmez-
akıllı ayrıklık testi, çünkü her iki RHS de aynı terminal ile başlar, özdeş
daha şiddetli. Bu sorun, sol faktoring adı verilen bir işlemle hafifletilebilir .
Şimdi sol faktoringe gayri resmi bir bakış atıyoruz. için kurallarımızı göz önünde bulundurun
<değişken>. Her iki RHS de tanımlayıcı ile başlar. Tanımlayıcıyı takip eden parçalar
iki RHS (boş dize) ve [<ifade>]'dir. İki kural olabilir
aşağıdaki iki kuralla değiştirilmelidir:
<değişken> → tanımlayıcı <yeni>
<yeni> → [<ifade>]

Sayfa 211
190
Bölüm 4 Sözcük ve Sözdizimi Analizi
Bu iki kuralın birlikte aynı alanı oluşturduğunu görmek zor değil.
başladığımız iki kural olarak guage. Ancak bu ikisi geçer
ikili ayrıklık testi.
Dilbilgisi özyinelemeli bir ayrıştırıcı için temel olarak kullanılıyorsa,
sol faktoringe alternatif mevcuttur. EBNF uzantısı ile sorun
sol faktoring çözümüne çok benzer bir şekilde kaybolur. Düşünmek
<değişken> için yukarıdaki orijinal kurallar. Alt simge tarafından isteğe bağlı yapılabilir
olduğu gibi köşeli parantez içine alarak
<değişken> → tanımlayıcı [ [<ifade] ]
Bu kuralda, dıştaki parantezler içinde ne olduğunu gösteren metasembollerdir.
İsteğe bağlı. İç parantezler, programlama şeridinin terminal sembolleridir.
guage tarif ediliyor. Mesele şu ki, iki kuralı tek bir kuralla değiştirdik.
aynı dili oluşturan ancak ikili ayrıklık testini geçen kural.
Sol faktoring için resmi bir algoritma Aho ve ark. (2006). Ayrıldı
faktoring, gramerlerin tüm ikili ayrıklık problemlerini çözemez. bazılarında
durumlarda, sorunu ortadan kaldırmak için kurallar başka şekillerde yeniden yazılmalıdır.
4.5 Aşağıdan Yukarıya Ayrıştırma
Bu bölüm, aşağıdan yukarıya ayrıştırmanın genel sürecini tanıtır ve şunları içerir:
LR ayrıştırma algoritmasının bir açıklaması.
4.5.1 Aşağıdan Yukarıya Ayrıştırıcılar için Ayrıştırma Problemi
Aritmetik ifadeler için aşağıdaki dilbilgisini göz önünde bulundurun:
E → E + T | T
T → T * F | F
F → ( E ) | İD
Bu dilbilgisinin aşağıdakiyle aynı aritmetik ifadeleri ürettiğine dikkat edin.
Örnek Bölüm 4.4'te. Aradaki fark, bu dilbilgisinin özyinelemeli bırakılmasıdır,
hangi aşağıdan yukarıya ayrıştırıcılar için kabul edilebilir. Ayrıca alt için dilbilgisi-
up ayrıştırıcıları normalde belirtmek için kullanılanlar gibi metasemboller içermez
BNF uzantıları. Aşağıdaki en sağdaki türetme bu dilbilgisini göstermektedir:
E => E + T
=> E + T * F
=> E + T * kimliği
=> E + F * kimliği
=> E + kimlik * kimlik
=> T + id * id
=> F + id * id
=> id + id * id

Sayfa 212
4.5 Aşağıdan Yukarıya Ayrıştırma 191
Bu türetmedeki her bir cümle biçiminin altı çizili kısmı, RHS'dir.
önceki cümle formunu almak için karşılık gelen LHS olarak yeniden yazılır. bu
aşağıdan yukarıya ayrıştırma işlemi, en sağdaki türetmenin tersini üretir.
Bu nedenle, örnek türetmede, aşağıdan yukarıya bir ayrıştırıcı, son cümle ile başlar.
(giriş cümlesi) oluşturur ve cümle formlarının sırasını üretir.
orada kalan tek şey, bu dilbilgisinde E olan başlangıç ​​​​sembolü olana kadar.
her adımda, aşağıdan yukarıya ayrıştırıcının görevi, belirli RHS'yi,
tanıtıcı, sonraki (önceki) almak için yeniden yazılması gereken cümle biçiminde
cümle formu. Daha önce belirtildiği gibi, doğru bir cümle formu daha fazlasını içerebilir.
birden fazla RHS. Örneğin, doğru cümle biçimi
E + T * kimliği
üç RHS, E + T, T ve id içerir. Bunlardan sadece biri tutamaçtır. İçin
örneğin, RHS E + T bu cümle biçiminde yeniden yazılmak üzere seçilmişse,
sonuçta ortaya çıkan cümle biçimi E * id olur, ancak E * id yasal bir hak değildir
verilen dilbilgisi için cümle formu.
Doğru bir cümlesel formun tutamacı benzersizdir. Aşağıdan yukarıya bir görev
ayrıştırıcı, üretilebilecek herhangi bir doğru cümlesel formun tanıtıcısını bulmaktır.
ilişkili dilbilgisi ile ilişkilendirilir. Resmi olarak, tanıtıcı şu şekilde tanımlanır:
Tanım: doğru cümlesel formun tutamacıdır =
w eğer ve
sadece S =7* rm ise
AW = 7 rm
w
Bu tanımda, =7 rm en sağdaki türetme adımını belirtir ve =7* rm
sıfır veya daha fazla en sağdaki türetme adımlarını belirtir. Her ne kadar bir tanımı
tutamak matematiksel olarak özlüdür, tutamacı bulmakta çok az yardım sağlar
belirli bir sağ cümle formunun. Aşağıda, tanımlarını veriyoruz
tutamaçlarla ilgili cümle formlarının birkaç alt dizisi. Amaç
Bunlardan biri, tutamaçlar hakkında bazı sezgiler sağlamaktır.
Tanım: Bir olan ifade sağ cümlesel formunun ve ancak eğer
S =7* = 1 A 2 =7 + 1
2
Bu tanımda =>+, bir veya daha fazla türetme adımı anlamına gelir.
Tanım: eğer ve doğru cümle biçimindeki basit bir ifadedir
sadece S =7* = 1 ise A 2 =7 1
2
Bu iki tanım dikkatli bir şekilde karşılaştırıldığında, sadece farklı oldukları açıktır.
son türetme belirtiminde. İfadenin tanımı bir veya daha fazla kullanır
adımlar, basit ifadenin tanımı ise tam olarak bir adım kullanır.
İfade ve basit ifadenin tanımları aynı görünebilir
bir sap kadar pratik değer eksikliği, ama bu doğru değil. Ne olduğunu bir düşünün
ifade bir ayrıştırma ağacına göredir. Bu, yaprağın tüm yapraklarının ipidir.
Tüm ayrıştırmanın belirli bir iç düğümünde köklenen tial ayrıştırma ağacı
ağaç. Basit bir ifade, yalnızca kendisinden tek bir türetme adımı alan bir ifadedir.

Sayfa 213
192
Bölüm 4 Sözcük ve Sözdizimi Analizi
kök terminal olmayan düğüm. Bir ayrıştırma ağacı açısından, bir ifadeden türetilebilir.
bir veya daha fazla ağaç seviyesinde tek bir nonterminal, ancak basit bir ifade olabilir
sadece tek bir ağaç seviyesinde türetilmiştir. Şekil 4.3'te gösterilen ayrıştırma ağacını düşünün.
Şekil 4.3'teki ayrıştırma ağacının yaprakları cümle biçimini içerir.
E + T * kimliği. Üç dahili düğüm olduğu için üç ifade vardır.
Her bir iç düğüm, yaprakları bir cümle olan bir alt ağacın köküdür. Kök
tüm ayrıştırma ağacının düğümü, E, elde edilen tüm cümlesel formu üretir,
Bir ifade olan E + T * id. Dahili düğüm, T, T * id yapraklarını üretir,
bu başka bir ifadedir. Son olarak, dahili düğüm F, aynı zamanda
bir cümle. Yani, E + T * id cümle formunun cümleleri E + T * id, T * id,
ve kimlik. İfadelerin temel dilbilgisinde mutlaka RHS'ler olmadığına dikkat edin.
Basit ifadeler, ifadelerin bir alt kümesidir. Önceki örnekte,
tek basit ifade id'dir. Basit bir ifade, dilbilgisinde her zaman bir RHS'dir.
Cümleleri ve basit ifadeleri tartışmanın nedeni şudur: Tutamak
herhangi bir en sağdaki cümle biçiminin en soldaki basit ifadesidir. şimdi elimizde
Herhangi bir doğru cümle formunun tutamağını bulmanın oldukça sezgisel bir yolu, varsayalım.
dilbilgisine sahibiz ve bir ayrıştırma ağacı çizebiliriz. bulmak için bu yaklaşım
tutamaçlar elbette bir ayrıştırıcı için pratik değildir. (Zaten bir ayrıştırma ağacınız varsa,
neden bir ayrıştırıcıya ihtiyacınız var?) Tek amacı okuyucuya bazı
bir ayrıştırma ağacına göre bir tutamacın ne olduğuna dair sezgisel bir his;
tutamaçları cümle formları açısından düşünmeye çalışmak.
Şimdi aşağıdan yukarıya ayrıştırmayı ayrıştırma ağaçları açısından düşünebiliriz, ancak
ayrıştırıcının amacı bir ayrıştırma ağacı üretmektir. Bir için ayrıştırma ağacı verildiğinde
tüm cümle, yeniden yazılacak ilk şey olan tutamacı kolayca bulabilirsiniz.
önceki cümle formunu almak için cümlede. O zaman kol olabilir
ayrıştırma ağacından budanır ve işlem tekrarlanır. Köküne devam etmek
ayrıştırma ağacı, en sağdaki türetmenin tamamı oluşturulabilir.
4.5.2 Shift-Reduce Algoritmaları
Aşağıdan yukarıya ayrıştırıcılara genellikle kaydırma azaltma algoritmaları denir , çünkü kaydırma
ve azaltmak, belirttikleri en yaygın iki eylemdir. ayrılmaz bir parça
her aşağıdan yukarıya ayrıştırıcının bir yığınıdır. Diğer ayrıştırıcılarda olduğu gibi, girdi
Şekil 4.3
için bir ayrıştırma ağacı
E + T * kimliği
F
T
E
*
İD
+
T
E

Sayfa 214
4.5 Aşağıdan Yukarıya Ayrıştırma 193
aşağıdan yukarıya ayrıştırıcı, bir programın belirteçlerinin akışıdır ve çıktı bir
gramer kuralları dizisi. Kaydırma eylemi, bir sonraki giriş belirtecini üzerine taşır.
ayrıştırıcı yığını. Bir azaltma eylemi, üst taraftaki bir RHS'nin (tutamak) yerini alır.
ayrıştırıcı yığını, karşılık gelen LHS'ye göre. Bir programlama dili için her ayrıştırıcı
guage bir aşağı itilen otomattır ( PDA ), çünkü bir PDA için bir tanıyıcıdır.
bağlamdan bağımsız bir dil. Anlamak için PDA'larla samimi olmanıza gerek yok
yardımcı olmasına rağmen, aşağıdan yukarıya bir ayrıştırıcı nasıl çalışır. PDA çok basit
sembol dizilerini soldan sağa tarayan matematiksel makine. bir PDA
belleği olarak bir aşağı itme yığını kullandığı için bu şekilde adlandırılmıştır. PDA'lar kullanılabilir
bağlamdan bağımsız diller için tanıyıcı olarak. üzerinde bir dizi sembol verildiğinde
bağlamdan bağımsız bir dilin alfabesi, amaç için tasarlanmış bir PDA
dizenin dilde bir cümle olup olmadığını belirleyebilir. İçinde
PDA, bir ayrıştırma oluşturmak için gereken bilgiyi üretebilir.
cümle için ağaç.
Bir PDA ile, giriş dizgisi, her seferinde bir sembol olacak şekilde incelenir.
sağ. Girdi, başka bir yığında depolanmış gibi ele alınır,
çünkü PDA hiçbir zaman girişin en soldaki sembolünden fazlasını görmez.
Özyinelemeli iniş ayrıştırıcısının aynı zamanda bir PDA olduğunu unutmayın. Bu durumda yığın
alt program çağrılarını (diğerlerinin yanı sıra) kaydeden çalışma zamanı sisteminin sistemidir.
şeyler), dilbilgisinin terminal olmayanlarına karşılık gelir.
4.5.3 LR Ayrıştırıcıları
Birçok farklı aşağıdan yukarıya ayrıştırma algoritması geliştirilmiştir. Çoğu
bunlar, LR adı verilen bir işlemin varyasyonlarıdır. LR ayrıştırıcıları nispeten küçük bir
program ve belirli bir programlama dili için oluşturulmuş bir ayrıştırma tablosu
ölçü. Orijinal LR algoritması Donald Knuth (Knuth,
1965). Bazen denir Bu algoritma, kanonik LR değildi
üretildiği için yayınlanmasını takip eden yıllarda kullanılmıştır.
gerekli ayrıştırma tablosu büyük miktarda bilgisayar zamanı gerektiriyordu ve
hafıza. Daha sonra, kurallı LR tablosundaki çeşitli varyasyonlar,
oluşturma süreci geliştirilmiştir (DeRemer, 1971; DeRemer ve Pennello,
1982). Bunlar iki özellik ile karakterize edilir: (1) Çok daha azını gerektirirler.
kanoni-den daha gerekli ayrıştırma tablosunu üretmek için bilgisayar kaynakları
cal LR algoritması ve (2) daha küçük gramer sınıfları üzerinde çalışırlar.
kanonik LR algoritması.
LR ayrıştırıcılarının üç avantajı vardır:
1. Tüm programlama dilleri için oluşturulabilirler.
2. Soldan sağa mümkün olan en kısa sürede sözdizimi hatalarını tespit edebilirler.
tarama.
3. LR gramer sınıfı, tarafından ayrıştırılabilen sınıfın uygun bir üst kümesidir.
LL ayrıştırıcıları (örneğin, birçok sol özyinelemeli dilbilgisi LR'dir, ancak
hiçbiri LL değildir).
LR ayrıştırmasının tek dezavantajı elle üretmenin zor olmasıdır.
tam bir programlama dili için belirli bir dilbilgisi için ayrıştırma tablosu.

Sayfa 215
194
Bölüm 4 Sözcük ve Sözdizimi Analizi
Ancak bu ciddi bir dezavantaj değildir, çünkü birkaç program vardır.
girdi olarak bir dilbilgisi alan ve ayrıştırma tablosunu dis-
bu bölümde daha sonra tartışıldı.
LR ayrıştırma algoritmasının ortaya çıkmasından önce, bir dizi
bakarak doğru cümle formlarının tutamaçlarını bulan algoritmaların ayrıştırılması
olan cümlesel formun alt dizisinin hem solunda hem de sağında
kolu olduğundan şüpheleniliyor. Knuth'un içgörüsü, birinin etkili bir şekilde
ayrıştırmanın sonuna kadar şüpheli tutacağın soluna bakın
tutamaç olup olmadığını belirlemek için yığın. Ama içindeki tüm bilgiler
ayrıştırma işlemiyle ilgili ayrıştırma yığını şu şekilde temsil edilebilir:
yığının üstünde depolanabilen tek bir durum. Başka bir deyişle,
Knuth, girdi dizgisinin uzunluğundan bağımsız olarak,
cümlesel biçim veya ayrıştırma yığınının derinliği, yalnızca nispeten
ayrıştırma işlemi söz konusu olduğunda, az sayıda farklı durum.
Her durum bir durumla temsil edilebilir ve ayrıştırma yığınında saklanabilir,
yığındaki her dilbilgisi sembolü için bir durum sembolü. Yığının en üstünde
her zaman ilgili bilgileri temsil eden bir durum sembolü olacaktır.
ayrıştırmanın tüm geçmişinden geçerli zamana kadar. alt kullanacağız
ayrıştırıcı durumlarını temsil etmek için kodlanmış büyük S'ler.
Şekil 4.4, bir LR ayrıştırıcısının yapısını gösterir. ayrıştırmanın içeriği
bir LR ayrıştırıcısı için yığın aşağıdaki forma sahiptir:
S 0 X 1 S 1 X 2 c X m S m (üst)
burada S'ler durum sembolleri ve X'ler dilbilgisi sembolleridir. Bir LR ayrıştırıcısı
konfigürasyon, ayrıntılı formu olan bir dizi dizidir (yığın, girdi).
(S 0 x 1 S 1 x 2 S 2 Cx m G m , bir i bir i + 1 ca n $)
Şekil 4.4
Bir LR'nin yapısı
ayrıştırıcı
Yığını Ayrıştırma
Tepe
ayrıştırıcı
kod
Giriş
ayrıştırma
Tablo
S 0 X 1 S 1
X m S m
bir ben
$
bir ben+1
bir n
Giriş dizesinin sağ ucunda bir dolar işareti olduğuna dikkat edin. bu işaret konur
ayrıştırıcının başlatılması sırasında orada. Normal sonlandırma için kullanılır
ayrıştırıcı. Bu ayrıştırıcı yapılandırmasını kullanarak, LR ayrıştırıcısını resmi olarak tanımlayabiliriz.
ayrıştırma tablosuna dayanan süreç.

Sayfa 216
4.5 Aşağıdan Yukarıya Ayrıştırma 195
Bir LR ayrıştırma tablosunun ACTION ve GOTO adlı iki bölümü vardır. bu
Tablonun ACTION kısmı, ayrıştırıcının yaptığı çoğu şeyi belirtir. devleti var
satır etiketleri olarak semboller ve dilbilgisinin terminal sembolleri
sütun etiketleri. Durum tarafından temsil edilen geçerli bir ayrıştırıcı durumu göz önüne alındığında
ayrıştırma yığınının üstündeki sembolü ve girdinin bir sonraki sembolü (belirteç),
ayrıştırma tablosu, ayrıştırıcının ne yapması gerektiğini belirtir. İki birincil ayrıştırıcı eylemi
kaydırır ve azaltır. Ayrıştırıcı, sonraki giriş sembolünü
yığını ayrıştırın veya yığının üstünde tutamacı zaten var, bu da azaltıyor
RHS'si tanıtıcı ile aynı olan kuralın LHS'si. Diğer iki işlem
mümkündür: kabul et, bu, ayrıştırıcının işlemi başarıyla tamamladığı anlamına gelir.
girişin ayrıştırılması ve ayrıştırıcının bir sözdizimi algıladığı anlamına gelen hata
hata.
LR ayrıştırma tablosunun GOTO bölümünün satırları durum sembollerine sahiptir
etiketler olarak. Tablonun bu kısmı, sütun etiketleri olarak terminal olmayanlara sahiptir. Değerler
tablonun GOTO bölümünde hangi durum sembolüne basılması gerektiğini belirtin
bir indirgeme tamamlandıktan sonra ayrıştırma yığınına, yani
tanıtıcı ayrıştırma yığınından kaldırıldı ve yeni terminal dışı
ayrıştırma yığınına itildi. Özel sembol satırda bulunur
etiketi, tanıtıcıdan sonra ayrıştırma yığınının üstündeki durum sembolü olan ve
ilişkili durum sembolleri kaldırılmıştır. GOTO sütunu
kullanılan tablo, kullanılan kuralın LHS'si olan etikete sahip tablodur.
azalma.
Aşağıdaki aritmetik ifadeler için geleneksel dilbilgisini göz önünde bulundurun:
1. E → E + T
2. E → T
3. T → T * F
4. T → F
5. F → ( E )
6. F → kimlik
Bu dilbilgisinin kuralları, başvuruda bulunmanın basit bir yolunu sağlamak için numaralandırılmıştır.
onları bir ayrıştırma tablosunda.
Şekil 4.5, bu dilbilgisi için LR ayrıştırma tablosunu göstermektedir. Kısaltmalar
eylemler için kullanılır: R azaltmak için ve S kaydırmak için. R4, kural 4'ü kullanarak azaltmak anlamına gelir;
S6, bir sonraki giriş sembolünü yığına kaydırmak ve S6 durumunu yığına itmek anlamına gelir.
yığın. EYLEM tablosundaki boş konumlar, sözdizimi hatalarını gösterir. İçinde
tam ayrıştırıcı, bunlarda hata işleme rutinlerine çağrılar olabilir.
LR ayrıştırma tabloları, aşağıdaki gibi bir yazılım aracı kullanılarak kolayca oluşturulabilir:
dilbilgisini girdi olarak alan yacc (Johnson, 1975). LR ayrıştırmasına rağmen
tablolar, gerçek bir programlama dilinin grameri için elle üretilebilir.
Bu görev uzun, sıkıcı ve hataya açık olurdu. Gerçek derleyiciler için,
LR ayrıştırma tabloları her zaman yazılım araçlarıyla oluşturulur.
Bir LR ayrıştırıcısının ilk yapılandırması şu şekildedir:
(S 0 , bir 1 ca n $)

Sayfa 217
196
Bölüm 4 Sözcük ve Sözdizimi Analizi
Ayrıştırıcı eylemleri gayri resmi olarak şu şekilde tanımlanır:
1. Shift işlemi basittir: Bir sonraki giriş sembolü,
Yığın, Shift belirtiminin bir parçası olan durum simgesiyle birlikte
EYLEM tablosunda.
2. Bir Azaltma eylemi için tutamaç yığından çıkarılmalıdır.
Çünkü yığındaki her dilbilgisi sembolü için bir durum sembolü vardır,
yığından kaldırılan sembollerin sayısı, sayının iki katıdır
tutamaçtaki sembollerin sayısı. Tutamacı ve ilişkili olduğu yeri çıkardıktan sonra
durum sembolleri, kuralın LHS'si yığına itilir. Nihayet,
GOTO tablosu kullanılır, satır etiketi ise
tutamaç ve durum sembolleri kaldırıldığında ortaya çıkar.
yığın ve sütun etiketi, LHS olan terminal olmayandır.
indirgemede kullanılan kural.
3. Eylem Kabul Et olduğunda, ayrıştırma tamamlanmıştır ve herhangi bir hata oluşmamıştır.
bulundu.
4. Eylem Hata olduğunda, ayrıştırıcı bir hata işleme yordamı çağırır.
LR konseptine dayalı birçok ayrıştırma algoritması olmasına rağmen, bunlar
yalnızca ayrıştırma tablosunun yapısında farklılık gösterir. Tüm LR ayrıştırıcıları bunu aynı şekilde kullanır
ayrıştırma algoritması
LR ayrıştırma işlemine aşina olmanın belki de en iyi yolu,
bir örnek aracılığıyla. Başlangıçta, ayrıştırma yığını tek bir sembol olan 0'a sahiptir.
Şekil 4.5
LR ayrıştırma tablosu
bir aritmetik için
ifade dilbilgisi
Eylem
git
İD
+
*
S5
S5
S5
S5
S4
S4
S4
S4
0
1
2
3
4
5
6
7
8
9
10
11
S6
S7
R2
R4
R4
Belirtmek, bildirmek
(
)
$
E
T
F
R6
R6
S6
R1
R3
R5
R2
R4
R6
S11
R1
R3
R5
R4
R6
R1
R3
R5
R3
R5
kabul
R2
S7
1
2
3
2
3
3
8
9
10

Sayfa 218
Özet 197
ayrıştırıcının 0 durumunu temsil eder. Giriş, giriş dizesini bir
bitiş işareti, bu durumda sağ ucuna iliştirilmiş bir dolar işareti. Her adımda,
ayrıştırıcı eylemleri, en üstteki (Şekil 4.4'te en sağdaki) sembol tarafından belirlenir.
ayrıştırma yığını ve sonraki (Şekil 4.4'te en soldaki) girdi belirteci. kor-
doğru eylem, ekranın EYLEM bölümünün ilgili hücresinden seçilir.
ayrıştırma tablosu. Ayrıştırma tablosunun GOTO kısmı, bir azaltma işleminden sonra kullanılır.
GOTO'nun hangi durum sembolünün üzerine yerleştirileceğini belirlemek için kullanıldığını hatırlayın.
bir azaltmadan sonra yığını ayrıştırın.
Aşağıda, LR ayrıştırıcısını kullanarak id + id * id dizesinin bir ayrıştırmasının izi bulunmaktadır.
algoritması ve Şekil 4.5'te gösterilen ayrıştırma tablosu.
Verilen gramerlerden LR ayrıştırma tabloları oluşturmak için algoritmalar,
Aho ve ark. (2006), aşırı karmaşık değil ama ötesinde
programlama dilleri üzerine bir kitabın kapsamı. Daha önce belirtildiği gibi, orada
LR ayrıştırıcıları oluşturmak için kullanılabilen bir dizi farklı yazılım sistemidir.
tablolar.
ÖZET
Sözdizimi analizi, dil uygulamasının ortak bir parçasıdır, ne olursa olsun
uygulama yaklaşımı kullanılmıştır. Sözdizimi analizi normalde resmi bir
uygulanan dilin sözdizimi açıklaması. Bağlamdan bağımsız bir gram-
BNF olarak da adlandırılan mar, tanımlamak için en yaygın yaklaşımdır.
sözdizimi. Sözdizimi analizinin görevi genellikle iki kısma ayrılır: sözlüksel
analiz ve sözdizimi analizi. Sözcüksel ayırmanın birkaç nedeni vardır.
analiz—yani, basitlik, verimlilik ve taşınabilirlik.
Yığın
Giriş
Eylem
0
kimlik + kimlik * kimlik $
5. vardiya
0id5
+ kimlik * kimlik $
6'yı azaltın (GOTO[0, F] kullanın)
0F3
+ kimlik * kimlik $
4'ü azaltın (GOTO[0, T] kullanın)
0T2
+ kimlik * kimlik $
2'yi azaltın (GOTO[0, E] kullanın)
0E1
+ kimlik * kimlik $
vardiya 6
0E1+6
kimlik * kimlik $
5. vardiya
0E1+6id5
* kimlik $
6'yı azaltın (GOTO[6, F] kullanın)
0E1+6F3
* kimlik $
4'ü azaltın (GOTO[6, T] kullanın)
0E1+6T9
* kimlik $
7 vardiya
0E1+6T9*7
kimlik $
5. vardiya
0E1+6T9*7id5
$
6'yı azaltın (GOTO[7, F] kullanın)
0E1+6T9*7F10
$
3'ü azaltın (GOTO[6, T] kullanın)
0E1+6T9
$
1'i azaltın (GOTO[0, E] kullanın)
0E1
$
Kabul

Sayfa 219
198
Bölüm 4 Sözcük ve Sözdizimi Analizi
Sözlüksel çözümleyici, küçük ölçekli parçaları izole eden bir kalıp eşleştiricidir.
sözlük adı verilen bir programın Sözlükler, aşağıdaki gibi kategorilerde ortaya çıkar:
tamsayı değişmezleri ve adları. Bu kategorilere jeton denir. Her belirteç
sözlükle birlikte sözlüksel ana-
lyzer üretir. Bir sözlük oluşturmak için üç farklı yaklaşım vardır.
analizör: tabloya dayalı bir analizör için bir tablo oluşturmak üzere bir yazılım aracı kullanmak,
böyle bir tabloyu elle oluşturmak ve bir durum diyagramını uygulamak için kod yazmak
uygulanan dilin belirteçlerinin açıklaması. devlet diya-
geçiş için karakter sınıfları kullanılıyorsa belirteçler için gram oldukça küçük olabilir.
her olası karakter için geçişlere sahip olmak yerine,
durum düğümü. Ayrıca, durum diyagramı, bir tablo araması kullanılarak basitleştirilebilir.
ayrılmış kelimeleri tanır.
Sözdizimi çözümleyicilerinin iki amacı vardır: belirli bir programdaki sözdizimi hatalarını saptamak
ve bir ayrıştırma ağacı veya muhtemelen yalnızca oluşturmak için gereken bilgileri üretmek için
belirli bir program için böyle bir ağaç. Sözdizimi çözümleyicileri ya yukarıdan aşağıya, ortalama-
en soldaki türevleri ve yukarıdan aşağıya sırayla bir ayrıştırma ağacı oluştururlar veya
aşağıdan yukarıya, bu durumda en sağdaki türetmenin tersini oluştururlar
ve aşağıdan yukarıya doğru bir ayrıştırma ağacı. Açıkça her şey için çalışan ayrıştırıcılar
gramerlerin karmaşıklığı vardır O(n 3 ). Ancak, uygulamak için kullanılan ayrıştırıcılar
programlama dilleri için sözdizimi çözümleyicileri, açıklığın alt sınıfları üzerinde çalışır.
ous gramerleri ve karmaşıklığı O(n).
Özyinelemeli iniş ayrıştırıcısı, yazarak uygulanan bir LL ayrıştırıcısıdır.
doğrudan kaynak dilin gramerinden kodlayın. EBNF şu şekilde idealdir:
özyinelemeli iniş ayrıştırıcılar için temel. Özyinelemeli inişli bir ayrıştırıcının bir alt programı vardır.
gramerdeki her terminal olmayan için gram. Belirli bir gramer için kod
kuralın tek bir RHS'si varsa kural basittir. RHS soldan sağa incelenir.
Her terminal olmayan için kod, o terminal olmayan için ilişkili alt programı çağırır.
terminal olmayanın ürettiği her şeyi ayrıştıran terminal. Her terminal için,
kod, terminali bir sonraki giriş belirteci ile karşılaştırır. Eşleşirlerse,
kod, bir sonraki belirteci almak için sözcük çözümleyiciyi çağırır. yapmazlarsa,
alt program bir sözdizimi hatası bildirir. Bir kuralın birden fazla RHS'si varsa, alt-
program öncelikle hangi RHS'yi ayrıştırması gerektiğini belirlemelidir. mümkün olmalı
bu belirlemeyi bir sonraki girdi belirteci temelinde yapmak için.
İki farklı dilbilgisi özelliği, bir
dilbilgisine dayalı özyinelemeli iniş ayrıştırıcısı. Bunlardan biri sol özyinelemedir.
Bir gramerden doğrudan sola özyinelemeyi ortadan kaldırma süreci nispeten
basit. Her ne kadar onu kapsamasak da, her ikisini de doğrudan kaldırmak için bir algoritma var.
ve bir gramerden dolaylı sol özyineleme. Diğer sorun ile tespit edilir
bir ayrıştırma alt programının yapıp yapamayacağını test eden ikili ayrıklık testi
sonraki giriş belirteci temelinde hangi RHS'nin ayrıştırıldığını belirleyin.
İkili ayrıklık testinde başarısız olan bazı gramerler sıklıkla değiştirilebilir.
sol faktoring kullanarak geçmek için.
Aşağıdan yukarıya ayrıştırıcılar için ayrıştırma sorunu, dizinin alt dizisini bulmaktır.
almak için ilişkili LHS'ye indirgenmesi gereken mevcut cümle biçimi
en sağdaki türetmedeki sonraki (önceki) cümle biçimi. Bu alt dize
cümlesel formun tutamacı olarak adlandırılır. Bir ayrıştırma ağacı, sezgisel bir

Sayfa 220
Soruları gözden geçir 199
bir tutamacı tanımak için temel. Aşağıdan yukarıya ayrıştırıcı bir kaydırma azaltma algoritmasıdır,
çünkü çoğu durumda bir sonraki girdi sözlüğünü ayrıştırmaya kaydırır
yığının üstündeki tutamacı istifler veya azaltır.
Kaydırma azaltma ayrıştırıcılarının LR ailesi, en yaygın olarak kullanılan alt-
programlama dilleri için ayrıştırma yaklaşımı, çünkü bu ailedeki ayrıştırıcılar
alternatiflere göre çeşitli avantajlara sahiptir. Bir LR ayrıştırıcısı bir ayrıştırma yığını kullanır,
durumunu korumak için dilbilgisi sembolleri ve durum sembolleri içeren
ayrıştırıcı. Ayrıştırma yığınındaki en üstteki sembol her zaman bir durum sembolüdür.
ayrıştırma yığınındaki ayrıştırmayla ilgili tüm bilgileri temsil eder.
süreci. LR ayrıştırıcıları iki ayrıştırma tablosu kullanır: ACTION ve GOTO. bu
ACTION bölümü, üzerinde durum sembolü verildiğinde ayrıştırıcının ne yapması gerektiğini belirtir.
ayrıştırma yığınının üstü ve bir sonraki giriş belirteci. GOTO tablosu kullanılır
sonra ayrıştırma yığınına hangi durum sembolünün yerleştirilmesi gerektiğini belirlemek için
azaltma yapılmıştır.
İNCELEME SORULARI
1. Sözdizimi çözümleyicilerinin dilbilgisine dayalı olmasının üç nedeni nedir?
2. Sözlüksel analizin söz diziminden ayrılmasının üç nedenini açıklayın
analiz.
3. Sözlük ve belirteci tanımlayın .
4. Bir sözlük çözümleyicisinin temel görevleri nelerdir?
5. Sözlüksel bir çözümleyici oluşturmaya yönelik üç yaklaşımı kısaca açıklayın.
6. Durum geçiş diyagramı nedir?
7. Neden bireysel karakterler yerine karakter sınıfları kullanılıyor?
Sözlüksel bir analizör için bir durum diyagramının harf ve rakam geçişleri?
8. Sözdizimi analizinin iki farklı amacı nedir?
9. Yukarıdan aşağıya ve aşağıdan yukarıya ayrıştırıcılar arasındaki farkları tanımlayın.
10. Yukarıdan aşağıya bir ayrıştırıcı için ayrıştırma sorununu tanımlayın.
11. Aşağıdan yukarıya bir ayrıştırıcı için ayrıştırma sorununu tanımlayın.
12. Derleyicilerin neden yalnızca bir alt küme üzerinde çalışan ayrıştırma algoritmaları kullandığını açıklayın
tüm gramerlerden.
13. Belirteç kodları için neden sayılar yerine adlandırılmış sabitler kullanılır?
14. Bir özyinelemeli-inişli ayrıştırma alt programının nasıl yazıldığını açıklayın.
tek bir RHS ile kural.
15. Onları yasaklayan iki dilbilgisi özelliğini açıklayın.
yukarıdan aşağıya ayrıştırıcı için temel olarak kullanılır.
16. Belirli bir dilbilgisi ve cümle biçimi için İLK küme nedir?
17. İkili ayrıklık testini tanımlayın.
18. Sol faktoring nedir?

Sayfa 221
200
Bölüm 4 Sözcük ve Sözdizimi Analizi
19. Cümle biçiminde bir ifade nedir?
20. Cümle biçimindeki basit bir cümle nedir?
21. Cümlesel bir formun tutamacı nedir?
22. Hem yukarıdan aşağıya hem de yukarıdan aşağıya doğru olan matematiksel makine nedir?
aşağıdan yukarıya ayrıştırıcılar dayanmaktadır?
23. LR ayrıştırıcılarının üç avantajını tanımlayın.
24. LR ayrıştırma tekniğini geliştirirken Knuth'un görüşü neydi?
25. Bir LR ayrıştırıcısının ACTION tablosunun amacını tanımlayın.
26. Bir LR ayrıştırıcısının GOTO tablosunun amacını tanımlayın.
27. Sol özyineleme LR ayrıştırıcıları için bir sorun mudur?
PROBLEM SETİ
1. Aşağıdaki dil bilgisi kuralları için ikili ayrıklık testi yapın.
a. A → aB b cBB
B. B → aB bA aBb
C. C → aaA b kabin
2. Aşağıdaki dil bilgisi kuralları için ikili ayrıklık testi yapın.
a. S → aSb bAA
B. A → b{aB} a
C. B → aB bir
3. Bölüm 4.4.1'de verilen özyinelemeli iniş ayrıştırıcısının izini gösterin.
a + b * c dizesi .
4. Bölüm 4.4.1'de verilen özyinelemeli iniş ayrıştırıcısının izini gösterin.
a * (b + c) dizesi .
5. Aşağıdaki dilbilgisi ve doğru cümle biçimi verildiğinde, bir ayrıştırma çizin
ağaç ve ifadeleri ve basit ifadeleri ve ayrıca tanıtıcıyı gösterin.
S → aAb bBA A → ab aAB B → aB b
a. aaAbb
B. bBab
C. aaAbBb
6. Aşağıdaki dilbilgisi ve doğru cümle biçimi verildiğinde, bir ayrıştırma çizin
ağaç ve ifadeleri ve basit ifadeleri ve ayrıca tanıtıcıyı gösterin.
S → AbB bAc A → Ab aBB B → Ac cBb c
a. aAcccbbc
B. AbcaBccb
C. baBcBbbc

Sayfa 222
Programlama Alıştırmaları 201
7. Ayrıştırma yığını içeriği, giriş dizesi,
ve dilbilgisi ve ayrıştırma kullanılarak id * ( id + id ) dizesi için eylem
Bölüm 4.5.3'teki tablo.
8. Ayrıştırma yığını içeriği, giriş dizesi,
ve dilbilgisi ve ayrıştırma kullanılarak ( id + id ) * id dizesi için eylem
Bölüm 4.5.3'teki tablo.
9. Java veya C++' ın while ifadesini açıklayan bir EBNF kuralı yazın .
Bu kural için özyinelemeli iniş alt programını Java veya C++ ile yazın.
10. Java veya C++ için for ifadesini açıklayan bir EBNF kuralı yazın .
Bu kural için özyinelemeli iniş alt programını Java veya C++ ile yazın.
11. Dolaylı sol özyinelemeyi bir
Aho ve ark. (2006). Tümünü kaldırmak için bu algoritmayı kullanın
aşağıdaki dilbilgisinden sol özyineleme:
S → Aa Bb A → Aa Abc c Sb B → bb
PROGRAMLAMAALIŞTIRMALAR
1. Yorumların bir biçimini tanımak için bir durum diyagramı tasarlayın.
/* ile başlayan ve */ ile biten C tabanlı programlama dilleri .
2. Bilgisayarınızın kayan nokta değişmezlerini tanımak için bir durum diyagramı tasarlayın.
favori programlama dili.
3. Problem 1'in durum diyagramını uygulamak için kodu yazın ve test edin.
4. Problem 2'nin durum diyagramını uygulamak için kodu yazın ve test edin.
5. Aşağıdakileri tanımak için Bölüm 4.2'de verilen sözcük çözümleyicisini değiştirin.
ayrılmış sözcüklerin listesini oluşturun ve ilgili simge kodlarını döndürün:
for ( FOR_CODE , 30 ), if ( IF_CODE , 31 ), else ( ELSE_CODE , 32 ), iken
( WHILE_CODE , 33 ), do ( DO_CODE , 34 ), int ( INT_CODE , 35 ), float
( FLOAT_CODE , 36 ), geçiş ( SWITCH_CODE , 37 ).
6. Bölüm 4.2'de verilen sözcük çözümleyicisini (C ile yazılmış) dönüştürün.
Java'ya.
7. <expr>, <term> ve için özyinelemeli iniş ayrıştırıcı rutinlerini dönüştürün.
<faktör> Bölüm 4.4.1'de Java'ya verilmiştir.
8. Problem 1'deki testi geçen kurallar için bir özyinelemeli iniş yazın
Kurallar tarafından oluşturulan dili ayrıştıran ayrıştırma alt programı.
Lex adında bir sözcük çözümleyiciniz ve bir hata işleme alt biriminiz olduğunu varsayalım.
Bir sözdizimi hatası algılandığında çağrılan error adlı program .
9. Problem 2'deki testi geçen kurallar için bir özyinelemeli iniş yazın
Kurallar tarafından oluşturulan dili ayrıştıran ayrıştırma alt programı.
Lex adında bir sözcük çözümleyiciniz ve bir hata işleme alt biriminiz olduğunu varsayalım.
Bir sözdizimi hatası algılandığında çağrılan error adlı program .
10. Bölüm 4.5.3'te verilen LR ayrıştırma algoritmasını uygulayın ve test edin.

Sayfa 223
Bu sayfa bilerek boş bırakılmıştır

Sayfa 224
203
5.1 Giriş
5.2 İsimler
5.3 Değişkenler
5.4 Bağlama Kavramı
5.5 Kapsam
5.6 Kapsam ve Ömür
5.7 Referans Ortamları
5.8 Adlandırılmış Sabitler
5
İsimler, Bağlamalar,
ve Kapsamlar

Sayfa 225
204
Bölüm 5 İsimler, Bağlar ve Kapsamlar
Bu bölümde, değişkenlerin temel anlamsal sorunları tanıtılmaktadır. o
programdaki isimlerin ve özel kelimelerin doğasını açıklayarak başlar.
ming dilleri. Tür, adres ve
değer, daha sonra takma ad sorunu da dahil olmak üzere tartışılır. önemli kavramlar
farklı olası dahil olmak üzere bağlama ve bağlama süreleri daha sonra tanıtılır.
değişken nitelikler için bağlama süreleri ve bunların dört farklı kategoriyi nasıl tanımladıkları
değişkenler. Bunu takiben, isimler için çok farklı iki kapsam kuralı, statik ve
dinamik, bir referans ortamı kavramı ile birlikte açıklanmıştır.
Beyan. Son olarak, adlandırılmış sabitler ve değişken başlatma tartışılmıştır.
5.1 Giriş
Zorunlu programlama dilleri, değişen derecelerde,
temel alınan von Neumann bilgisayar mimarisi. Mimarinin iki
birincil bileşenleri, hem talimatları hem de verileri depolayan belleğidir.
ve içeriğini değiştirmek için işlemler sağlayan işlemcisi
hafıza. Makinenin bellek hücreleri için bir dilde soyutlamalar
değişkenlerdir. Bazı durumlarda, soyutlamaların özellikleri çok
hücrelerin özelliklerine yakın; bunun bir örneği bir tamsayı değişkenidir,
genellikle doğrudan bir veya daha fazla bellek baytında temsil edilir. Diğer
durumlarda, soyutlamalar donanımın organizasyonundan çok uzaktır.
bir yazılım eşlemesi gerektiren üç boyutlu bir dizide olduğu gibi bellek
soyutlamayı destekleyen işlev.
Bir değişken, özellikler veya nitelikler topluluğu ile karakterize edilebilir.
Bunlardan en önemlisi, programlamada temel bir kavram olan tiptir.
Diller. Bir dilin veri tiplerini tasarlamak, çeşitli
hususlar ele alınacaktır. (Veri türleri Bölüm 6'da tartışılmaktadır.) En çok
Bu konulardan önemli olan, değişkenlerin kapsamı ve yaşam süresidir.
İşlevsel programlama dilleri, ifadelerin adlandırılmasına izin verir. Bunlar
adlandırılmış ifadeler, zorunlu olarak değişken adlarına yapılan atamalar gibi görünür
fakat değiştirilemeyecekleri için temelde farklıdırlar. Böyle,
bunlar zorunlu dillerin adlandırılmış sabitleri gibidir. saf fonksiyonel
diller, zorunlu dillerdeki gibi değişkenlere sahip değildir.
Ancak, birçok işlevsel dil bu tür değişkenleri içerir.
Bu kitabın geri kalanında, dil ailelerine sıklıkla değinilecektir.
sanki tek dillermiş gibi. Örneğin, Fortran tüm sürümler anlamına gelecektir.
Fortran'ın. Bu Adana için de geçerli. Benzer şekilde, C'ye yapılan bir referans,
C'nin orijinal versiyonu ile C89 ve C99. Bir dilin belirli bir sürümü olduğunda
isimlendirilmiş olması, konunun diğer aile üyelerinden farklı olmasından kaynaklanmaktadır.
Tartışılmakta. Bir dilin sürümünün adına artı işareti (+) eklersek,
adlandırılmış olanla başlayan dilin tüm sürümleri anlamına gelir. Örneğin,
Fortran 95+, Fortran 95 ile başlayan tüm Fortran sürümleri anlamına gelir.
C tabanlı diller , C, Objective-C, C++, Java ve C# için kullanılacaktır. 1
1. C-tabanlı dil olarak JavaScript ve PHP betik dillerini dahil etmeye karar verdik.
ama atalarından biraz fazla farklı olduklarına karar verdiler.

Sayfa 226
5.2 İsimler 205
5.2 İsimler
Değişkenlerle ilgili tartışmamıza başlamadan önce, temellerden birinin tasarımı
değişkenlerin zihinsel nitelikleri, adları kapsanmalıdır. İsimler de ortak-
alt programlarla, biçimsel parametrelerle ve diğer program yapılarıyla bu
terim tanımlayıcısı genellikle name ile birbirinin yerine kullanılır .
5.2.1 Tasarım Konuları
Aşağıdakiler, adlar için birincil tasarım sorunlarıdır:
• İsimler büyük/küçük harfe duyarlı mı?
• Dilin özel kelimeleri ayrılmış kelimeler mi yoksa anahtar kelimeler mi?
Bu konular aşağıdaki iki alt bölümde tartışılmaktadır.
çeşitli tasarım seçeneklerine örnekler.
5.2.2 İsim Formları
Bir isim bir programda bazı varlığı tanımlamak için kullanılan karakter dizesidir.
Fortran 95+, adlarında 31 karaktere kadar izin verir. C99'un uzunluğu yok
dahili adlarında sınırlama vardır, ancak yalnızca ilk 63 önemlidir. Harici
C99'daki adlar (kullanıcı tarafından işlenmesi gereken, dışta tanımlanan işlevler)
linker) 31 karakterle sınırlıdır. Java, C# ve Ada'daki İsimler
uzunluk sınırı yoktur ve içindeki tüm karakterler önemlidir.
C++, uygulanmasına rağmen, adlar üzerinde bir uzunluk sınırı belirtmez.
akıl hocaları bazen yapar.
Çoğu programlama dilindeki isimler aynı forma sahiptir:
harf, rakam ve harflerden oluşan bir dize tarafından takip edilen bir harf
alt çizgi karakterleri ( _ ). Alt çizgi karakterinin kullanılmasına rağmen
isimler oluşturmak için aktörler 1970'lerde ve 1980'lerde yaygın olarak kullanıldı, bu
uygulama artık çok daha az popüler. C tabanlı dillerde,
büyük ölçüde, sözde deve notasyonu ile değiştirildi
birden çok kelimeli bir ismin ilk kelime hariç tüm kelimeleri
myStack'te olduğu gibi büyük harfle yazılır . 2 Alt çizgi kullanımının
ve adlardaki karışık durum, bir programlama stili sorunudur, bir lan-
guage tasarım sorunu.
PHP'deki tüm değişken isimleri dolar işaretiyle başlamalıdır. İçinde
Bir değişken adının başındaki özel karakter olan Perl,
$ , @ veya % , türünü belirtir (her ne kadar
Diğer diller). Ruby'de, başındaki özel karakterler
Bir değişkenin adı @ veya @@ , değişkenin bir örnek veya sınıf olduğunu belirtir
sırasıyla değişken.
2. İçinde yazılan kelimelerin içinde genellikle büyük harfler olduğu için buna “deve” denir.
deve hörgücüne benziyor.
tarih notu
En eski programlama lan-
tek karakter kullanılan ölçüler
isimler. Bu gösterim doğaldı.
ral çünkü erken programlama
öncelikle matematikseldi,
ve matematikçiler uzun
kullanılan tek karakterli adlar
biçimsel olarak bilinmeyenler için
notlar.
Fortran ile kırdım
tek karakter geleneği
ad, altı karaktere kadar izin
adlarında yer alır.

Sayfa 227
206
Bölüm 5 İsimler, Bağlar ve Kapsamlar
Birçok dilde, özellikle C tabanlı dillerde, büyük harf ve küçük harf
isimlerdeki harfler farklıdır; yani, bu dillerdeki adlar büyük/ küçük harfe duyarlıdır .
Örneğin, C++'da şu üç ad farklıdır: rose , ROSE ve
Gül . Bazı insanlar için bu, okunabilirliğe ciddi bir zarar verir, çünkü isimler
çok benzer görünen aslında farklı varlıkları ifade eder. Bu anlamda, büyük/küçük harfe duyarlı-
ity, benzer görünen dil yapılarının yapması gereken tasarım ilkesini ihlal ediyor.
benzer anlamlara sahiptir. Ancak değişken isimleri büyük/küçük harfe duyarlı olan dillerde,
Her ne kadar Gül ve gül benzer, aralarında hiçbir bağlantı yoktur.
Açıkçası, büyük/küçük harf duyarlılığının adlar için kötü olduğu konusunda herkes hemfikir değildir. İçinde
C, büyük/küçük harf duyarlılığı sorunlarından, değişkenin
isimler büyük harf içermez. Ancak Java ve C#'da sorun
lem'den kaçılamaz çünkü önceden tanımlanmış adların çoğu her ikisini de içerir
Büyük ve küçük harfler. Örneğin, dönüştürmek için Java yöntemi
bir tam sayı değeri için bir dizge olup parseInt ve gibi yazımlar parseInt ve
parseint tanınmaz. Bu bir yazılabilirlik sorunu değil,
okunabilirlik, çünkü belirli vaka kullanımını hatırlama ihtiyacı onu daha fazla yapar
doğru programlar yazmak zor. Bu bir tür hoşgörüsüzlüktür.
derleyici tarafından uygulanan dil tasarımcısı.
5.2.3 Özel Kelimeler
Programlama dillerinde özel kelimeler programları daha kullanışlı hale getirmek için kullanılır.
gerçekleştirilecek eylemleri adlandırarak okunabilir. ayırmak için de kullanılırlar.
ifadelerin ve programların sözdizimsel bölümleri. Çoğu dilde özel kelimeler
ayrılmış kelimeler olarak sınıflandırılır, bu da program tarafından yeniden tanımlanamayacakları anlamına gelir.
mers, ancak bazılarında yalnızca anahtar kelimelerdir, bu da yeniden tanımlanabilecekleri anlamına gelir.
Bir anahtar kelime sadece özel bir programlama dilinin bir kelimedir
belirli bağlamlar. Fortran, yaygın olarak kullanılan tek dildir.
özel kelimeler anahtar kelimelerdir. Fortran'da, Tamsayı kelimesi bulunduğunda
bir ifadenin başlangıcı ve ardından bir isim, bir anahtar kelime olarak kabul edilir
Bu, ifadenin bildirimsel bir ifade olduğunu gösterir. Ancak eğer kelime
Tamsayı , atama operatörü tarafından takip edilir, bir değişken olarak kabul edilir.
isim. Bu iki kullanım aşağıda gösterilmiştir:
tamsayı elma
tamsayı = 4
Fortran derleyicileri ve Fortran programlarını okuyan kişiler ayırt etmelidir.
bağlama göre isimler ve özel kelimeler arasında.
Bir özel amaçlı sözcük bir programlama dili özel bir kelime olduğunu kanserine
isim olarak kullanılamaz. Bir dil tasarımı seçeneği olarak, ayrılmış kelimeler daha iyidir
çünkü anahtar kelimeleri yeniden tanımlama yeteneği kafa karıştırıcı olabilir. İçin
örneğin, Fortran'da aşağıdaki ifadeler kullanılabilir:
Tamsayı Gerçek
gerçek tamsayı

Sayfa 228
5.3 Değişkenler 207
Bu ifadeler, Real program değişkeninin Tamsayı türünde olduğunu bildirir.
ve değişken tamsayı olması Gerçek tip. 3 Garip olmanın yanı sıra
bu beyan beyanlarının görünümü, Real ve Inte-
ger'in programın başka bir yerinde değişken isimleri olarak kullanılması, pro-
gram okuyucular
Ayrılmış kelimelerle ilgili olası bir sorun var: Eğer dil
çok sayıda ayrılmış kelime içeriyorsa, kullanıcı yapmakta zorluk çekebilir.
rezerve edilmemiş isimlerin kaydedilmesi. Bunun en iyi örneği COBOL'dur.
300 ayrılmış kelimeye sahiptir. Ne yazık ki, en sık seçilenlerden bazıları
programcıların adları ayrılmış sözcükler listesindedir—örneğin, LENGTH ,
ALT , HEDEF ve COUNT .
Bu kitaptaki program kodu örneklerinde, ayrılmış sözcükler
kalın yüz
Çoğu dilde, diğer program birimlerinde tanımlanan adlar, örneğin
Java paketleri ve C ve C++ kitaplıkları bir programa görünür hale getirilebilir. Bunlar
adlar önceden tanımlanmıştır, ancak yalnızca açıkça içe aktarılırsa görünür. Bir kez ithal,
yeniden tanımlanamazlar.
5.3 Değişkenler
Bir program değişkeni, bir bilgisayar bellek hücresinin veya koleksiyonunun bir soyutlamasıdır.
hücrelerin Programcılar genellikle değişken adlarını bellek konumlarının adları olarak düşünürler.
Ancak bir değişkende sadece bir addan çok daha fazlası vardır.
Makine dillerinden montaj dillerine geçiş büyük ölçüde
veriler için mutlak sayısal bellek adreslerinin adlarla değiştirilmesi,
programlar çok daha okunabilir ve bu nedenle yazılması ve bakımı daha kolaydır. o
adım ayrıca manuel mutlak adresleme probleminden bir kaçış sağladı,
çünkü isimleri gerçek adreslere çeviren tercüman da
bu adresler.
Bir değişken, altılı nitelik olarak karakterize edilebilir: (isim, adres,
değer, tür, yaşam süresi ve kapsam). için bu çok karmaşık görünse de
görünüşte bu kadar basit bir kavram, durumu açıklamanın en net yolunu sağlar.
değişkenlerin çeşitli yönleri.
Değişken niteliklere ilişkin tartışmamız, önemli olanın incelenmesine yol açacaktır.
takma adlar, bağlama, bağlama süreleri, bildirimler, kapsam belirleme ile ilgili kavramlar
kurallar ve referans ortamları.
Değişkenlerin adı, adresi, türü ve değer özellikleri,
aşağıdaki alt bölümler. Ömür ve kapsam özellikleri şurada tartışılmaktadır:
Sırasıyla Bölüm 5.4.3 ve 5.5.
3. Tabii ki, böyle bir kod yazacak herhangi bir profesyonel programcı, iş beklememelidir.
güvenlik.

Sayfa 229
208
Bölüm 5 İsimler, Bağlar ve Kapsamlar
5.3.1 Ad
Değişken adları, programlarda en yaygın kullanılan adlardır. Onlar dis-
varlık adlarının genel bağlamında Bölüm 5.2'de uzun uzadıya ele alınmıştır.
programlar. Çoğu değişkenin adı vardır. Üzerinde tartışılmayanlar
Bölüm 5.4.3.3.
5.3.2 Adres
Adres bir değişkenin o olan makine bellek adresi
Birleşmiş. Bu ilişkilendirme ilk bakışta göründüğü kadar basit değildir. birçoğunda
dillerde aynı değişkenin farklı değişkenlerle ilişkilendirilmesi mümkündür.
Programda farklı zamanlarda adresler. Örneğin, bir alt program varsa
alt program çalıştırıldığında çalışma zamanı yığınından ayrılan yerel bir değişken
çağrılırsa, farklı çağrılar, o değişkenin farklı adreslere sahip olmasına neden olabilir.
Bunlar bir anlamda aynı değişkenin farklı örneklemeleridir.
Değişkenleri adreslerle ilişkilendirme süreci daha ayrıntılı olarak tartışılmaktadır.
Bölüm 5.4.3. Alt programlar ve aktivasyonları için bir uygulama modeli
Bölüm 10'da tartışılmaktadır.
Bir değişkenin adresi bazen onun l - değeri olarak adlandırılır , çünkü
adres, bir değişkenin adı sol tarafta göründüğünde gerekli olan şeydir
bir görevden.
Aynı adrese sahip birden fazla değişken olması mümkündür. Ne zaman
aynı bellek konumuna erişmek için birden fazla değişken adı kullanılabilir,
değişkenlere takma ad denir . Aliasing, okunabilirliğe bir engeldir çünkü
bir değişkenin değerinin farklı bir değişkene atanarak değiştirilmesine izin verir.
hünerli. Örneğin, toplam ve toplam adlı değişkenler takma adlarsa, herhangi bir değişiklik
değerine toplam de değerini değiştirir toplamı ve tersi. bir okuyucu
program her zaman toplamın ve toplamın farklı isimler olduğunu hatırlamalıdır.
aynı bellek hücresi için. Çünkü bir dosyada herhangi bir sayıda takma ad olabilir.
program, bu pratikte çok zor olabilir. Aliasing ayrıca program yapar
doğrulama daha zor.
Takma adlar, programlarda birkaç farklı şekilde oluşturulabilir. Bir ortak
C ve C++ 'da yol sendika türleriyle birliktedir. Sendikalar uzun uzun tartışılıyor
Bölüm 6.
Aynı belleğe işaret ettiklerinde iki işaretçi değişkeni takma addır
yer. Aynısı referans değişkenler için de geçerlidir. Bu tür bir takma ad basitçe
işaretçilerin ve referansların doğasının bir yan etkisi. Bir C++ işaretçisi ayarlandığında
adlandırılmış bir değişkene işaret etmek için, işaretçi, başvurudan çıkarıldığında ve değişkenin
ad takma adlardır.
Aliasing, alt program parametreleri aracılığıyla birçok dilde oluşturulabilir.
eter. Bu tür takma adlar Bölüm 9'da tartışılmaktadır.
Bir değişkenin bir adresle ilişkilendirildiği zaman çok
programlama dillerini anlamak için önemlidir. Bu konu dis-
Bölüm 5.4.3'te tartışılmıştır.

Sayfa 230
5.4 Bağlama Kavramı 209
5.3.3 Tip
Türü bir değişken değişken saklayabilir değerleri aralığını belirler
ve türün değerleri için tanımlanan işlemler kümesi. Örneğin,
int Java tip -2147483648 2147483647 arasında bir değer aralığını belirler
ve toplama, çıkarma, çarpma, bölme için aritmetik işlemler,
ve modül.
5.3.4 Değer
Değeri bir değişkenin hafıza hücre veya hücre içeriği olan birligidir
değişkenle birlikte verilmiştir. Bilgisayar belleğini şu terimlerle düşünmek uygundur:
arasında soyut hücrelerden ziyade fiziksel hücreler. Fiziksel hücreler veya tek tek
Adreslenebilir birimler, çoğu çağdaş bilgisayar belleğinin bayt boyutundadır,
bir bayt genellikle sekiz bit uzunluğundadır. Bu boyut çoğu için çok küçük
program değişkenleri. Soyut bir bellek hücresi, değişkenin gerektirdiği boyuta sahiptir.
ile ilişkilendirilebilir. Örneğin, kayan noktalı değerler
belirli bir uygulamanın belirli bir uygulamasında dört fiziksel bayt işgal edebilir
dilde, kayan noktalı bir değerin tek bir soyut alanı kapladığı düşünülür.
hafıza hücresi. Her basit yapılandırılmamış türün değeri,
tek bir soyut hücreyi işgal eder. Bundan böyle, bellek hücresi terimi soyut anlamına gelir.
hafıza hücresi.
Bir değişkenin değerine bazen onun r - değeri denir çünkü
değişkenin adı bir atamanın sağ tarafında göründüğünde gereklidir.
ment beyanı. r değerine erişmek için önce l değeri belirlenmelidir.
Bu tür belirlemeler her zaman basit değildir. Örneğin, kapsam belirleme kuralları
Bölüm 5.5'te tartışıldığı gibi, meseleleri oldukça karmaşık hale getirir.
5.4 Bağlama Kavramı
Bir bağlayıcı bir nitelik ve bir varlık gibi arasında bir ilişki olduğunu
bir değişken ile türü veya değeri arasında veya bir işlem ile bir sembol arasında
bol. Bir bağlamanın gerçekleştiği zamana bağlama zamanı denir . bağlama
ve bağlama süreleri, programlama semantiğinde öne çıkan kavramlardır.
Diller. Bağlamalar dil tasarım zamanında gerçekleşebilir, dil uygulaması
gönderme zamanı, derleme zamanı, yükleme zamanı, bağlantı zamanı veya çalışma zamanı. Örneğin,
yıldız işareti ( * ) genellikle çarpma işlemine bağlıdır.
dil tasarım zamanı. C'deki int gibi bir veri türü, bir dizi
dil uygulama zamanında olası değerler. Derleme zamanında, bir değişken
Java programında belirli bir veri türüne bağlıdır. Bir değişken bağlı olabilir
program belleğe yüklendiğinde bir depolama hücresine. Aynı bağ-
Bildirilen değişkenlerde olduğu gibi, bazı durumlarda çalışma zamanına kadar gerçekleşmez.
Java yöntemlerinde. Bir kitaplık alt programına yapılan bir çağrı, alt programa bağlıdır
bağlantı zamanında kod.

Sayfa 231
210
Bölüm 5 İsimler, Bağlar ve Kapsamlar
Aşağıdaki Java atama ifadesini göz önünde bulundurun:
say = say + 5;
Bu ödevin bölümleri için bazı bağlamalar ve bunların bağlama süreleri
açıklama şu şekilde:
Sayım türü derleme zamanında bağlıdır.
Sayının olası değerleri kümesi , derleyici tasarım zamanında bağlıdır.
• Operatör sembolünün anlamı +, derleme zamanında bağlanır.
işlenen türleri belirlenmiştir.
• Hazır bilgi 5'in dahili temsili derleyici tasarımına bağlıdır
zaman.
• Bu deyimle sayım değeri yürütme zamanında bağlanır.
Programın nitelikleri için bağlama sürelerinin tam olarak anlaşılması
varlıklar, bir programlama dilinin semantiğini anlamak için bir ön koşuldur.
ölçü. Örneğin, bir alt programın ne yaptığını anlamak için,
bir çağrıdaki gerçek parametrelerin, bir çağrıdaki biçimsel parametrelere nasıl bağlı olduğunu gösterir.
onun tanımı. Bir değişkenin mevcut değerini belirlemek için gerekli olabilir
değişkenin ne zaman depoya bağlı olduğunu ve hangi ifade veya
ifadeler.
5.4.1 Niteliklerin Değişkenlere Bağlanması
Bir bağlama, çalıştırma süresi başlamadan önce gerçekleşirse ve kalırsa statiktir
program yürütme boyunca değişmez. Bağlanma önce gerçekleşirse,
çalışma süresi veya programın yürütülmesi sırasında değişebilir, buna denir
dinamik . Bir değişkenin sanal ortamda bir depolama hücresine fiziksel olarak bağlanması
bellek ortamı karmaşıktır, çünkü adresin sayfası veya bölümü
hücrenin içinde bulunduğu alan, birçok kez hafızaya girip çıkabilir.
Program yürütme sırasındaki süreler. Bir anlamda, bu tür değişkenler bağlıdır ve
tekrar tekrar bağlanmaz. Ancak bu bağlamalar bilgisayar tarafından korunur.
donanım ve değişiklikler program ve kullanıcı tarafından görülmez. Çünkü
tartışma için önemli değiller, bunlarla ilgilenmiyoruz
donanım bağlamaları. Temel nokta, statik ile statik arasındaki farkı ayırt etmektir.
dinamik bağlamalar.
5.4.2 Tip Bağlantıları
Bir programda bir değişkene başvurulmadan önce, bir veriye bağlanmalıdır.
tip. Bu bağlamanın iki önemli yönü, türün nasıl belirlendiğidir.
ve bağlama gerçekleştiğinde. Türler statik olarak belirtilebilir
bir tür açık veya örtülü beyan.

Sayfa 232
5.4 Bağlama Kavramı 211
5.4.2.1 Statik Tip Bağlama
Bir açık bildirim bir programda bir deyim olduğunu listeleri değişken adları
ve belirli bir tür olduklarını belirtir. Bir örtülü beyan bir araçtır
yerine, varsayılan kurallar aracılığıyla türlerle değişkenleri ilişkilendirmenin
beyanname beyanları. Bu durumda, bir değişken adının ilk görünümü
program, örtük beyanını oluşturur. Hem açık hem de örtülü beyan-
türler için statik bağlantılar oluşturur.
Statik tip bağlama kullanan en yaygın kullanılan programlama dilleri
münhasıran ve 1960'ların ortalarından beri tasarlanmış, açık beyanlar gerektirir
(Perl, JavaScript, Ruby ve ML bazı istisnalardır).
Örtük değişken tipi bağlama, dil işlemcisi tarafından yapılır.
derleyici veya yorumlayıcı. Örtük için birkaç farklı temel vardır
değişken tip bağlamalar. Bunların en basiti adlandırma kurallarıdır. İçinde
bu durumda, derleyici veya yorumlayıcı, bir değişkeni,
değişken adının sözdizimsel biçimi. Örneğin, Fortran'da bir kimlik
Açıkça bildirilmeyen bir programda görünen fier, örtük olarak
aşağıdaki kurala göre bildirilir: Tanımlayıcı başlarsa
I , J , K , L , M veya N harflerinden biri veya bunların küçük harfli versiyonları ile
örtük olarak Tamsayı türü olarak bildirildi ; aksi takdirde, dolaylı olarak beyan edilir
olmak Gerçek türü.
Programcılar için küçük bir kolaylık olsalar da, örtük karar
açıklamalar, derlemeyi engelledikleri için güvenilirliğe zarar verebilir.
Bazı tipografik ve programcı hatalarını tespit etme süreci. İçinde
Fortran, programcı tarafından yanlışlıkla bildirilmeyen değişkenler
verilen varsayılan türler ve muhtemelen beklenmeyen nitelikler, bu da belirsizliğe neden olabilir
Teşhisi zor olan hatalar. Birçok Fortran programcısı artık şunları içerir:
beyanı programlarında hiçbirini ima etmez . Bu beyan talimat verir
derleyici herhangi bir değişkeni örtük olarak bildirmez, böylece potansiyelden kaçınır.
kazara bildirilmemiş değişkenlerle ilgili problemler.
Örtük bildirimlerle ilgili sorunlardan bazıları, zorunlu olarak önlenebilir.
Belirli türler için belirli özel karakterlerle başlayan adlar. İçin
örneğin, Perl'de $ ile başlayan herhangi bir isim bir skalerdir ve
bir dize veya sayısal bir değer. Bir ad @ ile başlıyorsa , bir dizidir; başlarsa
% ile karma bir yapıdır. 4 Bu, farklı isimler için farklı ad alanları yaratır.
değişkenler yazın. Bu senaryoda, @apple ve %apple adları ilgisizdir,
çünkü her biri farklı bir ad alanından. Ayrıca program okuyucu
adını okurken her zaman bir değişkenin türünü bilir. Bu tasarımın dikkat
Fortran'dan farklıdır, çünkü Fortran'ın hem örtük hem de açık beyanları vardır.
Bu nedenle, bir değişkenin türü mutlaka yazımdan belirlenemez.
adının anılması.
Başka bir tür örtük tür bildirimi bağlamı kullanır. Bu bazen
tür çıkarımı denir . Daha basit durumda, bağlam, değerin türüdür.
bir bildirim deyiminde değişkene atanır. Örneğin, C#'da bir var
4. Hem diziler hem de karmalar tür olarak kabul edilir; her ikisi de öğelerinde herhangi bir skaleri depolayabilir.

Sayfa 233
212
Bölüm 5 İsimler, Bağlar ve Kapsamlar
Bir değişkenin bildirimi, türü şu şekilde yapılan bir başlangıç ​​değeri içermelidir.
değişkenin türü. Aşağıdaki beyanları göz önünde bulundurun:
var toplam = 0;
var toplam = 0.0;
var name = "Fred";
Tipleri toplamı , toplam ve isim olan int , şamandıra ve dize sırasıyla.
Bunların statik olarak yazılan değişkenler olduğunu unutmayın; türleri için sabittir.
beyan edildikleri birimin ömrü.
Visual BASIC 9.0+, Go ve işlevsel diller ML, Haskell, OCaml,
ve F# ayrıca tür çıkarımını kullanır. Bu işlevsel dillerde, bağlam
bir ismin görünümü, türünü belirlemenin temelidir. Bu tür
çıkarsama Bölüm 15'te ayrıntılı olarak tartışılmaktadır.
5.4.2.2 Dinamik Tip Bağlama
Dinamik tip bağlama ile, bir değişkenin tipi bir bildirimle belirtilmez.
ne de adının yazılışıyla belirlenemez. Bunun yerine,
değişken, atama durumunda bir değer atandığında bir türe bağlanır.
ment. Atama ifadesi yürütüldüğünde, atanan değişken
sağ taraftaki ifadenin değerinin türüne bağlıdır.
atama. Böyle bir atama, değişkeni bir adrese de bağlayabilir ve
bir bellek hücresi, çünkü farklı türdeki değerler farklı miktarlarda
depolamak. Herhangi bir değişkene herhangi bir tür değeri atanabilir. Ayrıca, bir değişkenin
type, programın yürütülmesi sırasında herhangi bir sayıda değişebilir. Bu önemli
tipi dinamik olarak bağlı olan bir değişkenin tipinin
geçici.
Bir değişkenin türü statik olarak bağlı olduğunda, değişkenin adı
türü ve adının bir türe bağlı olduğu düşünülmelidir.
değişken aynı anda bağlıdır. Ancak, bir değişkenin türü dinami-
olarak bağlıysa, adının yalnızca geçici olarak bir şeye bağlı olduğu düşünülebilir.
tip. Gerçekte, değişkenlerin adları hiçbir zaman türlere bağlı değildir. isimler olabilir
değişkenlere bağlı ve değişkenler türlere bağlı olabilir.
Türlerin dinamik olarak bağlı olduğu diller önemli ölçüde farklıdır.
türlerin statik olarak bağlı olduğu türlerden. Birincil avantajı
değişkenlerin türlere dinamik olarak bağlanması, daha fazla programlama sağlamasıdır
esneklik. Örneğin, sayısal verileri işleyen bir program,
dinamik tür bağlama kullanır, genel bir program olarak yazılabilir, yani
herhangi bir sayısal türdeki verilerle uğraşma yeteneğine sahiptir. Veri türü ne olursa olsun
giriş kabul edilebilir, çünkü verilerin saklanacağı değişkenler
sonra veriler değişkenlere atandığında doğru türe bağlanabilir.
giriş. Buna karşılık, türlerin statik bağlanması nedeniyle, bir C yazılamaz.
Verinin türünü bilmeden verileri işleyen program.
1990'ların ortalarından önce, en yaygın olarak kullanılan programlama lan-
statik tip bağlama kullandı, birincil istisnalar bazı işlevseldir

Sayfa 234
5.4 Bağlama Kavramı 213
LISP gibi diller. Ancak, o zamandan beri önemli bir değişiklik oldu
dinamik tür bağlama kullanan dillere. Python, Ruby, JavaScript ve
PHP, tür bağlama dinamiktir. Örneğin, bir JavaScript komut dosyası şunları içerebilir:
aşağıdaki ifade:
liste = [10.2, 3.5];
list adlı değişkenin önceki türünden bağımsız olarak , bu atama
2 uzunluğundaki tek boyutlu bir dizinin adı olmasına neden olur.
Beyan
liste = 47;
önceki örnek atamayı takip ettiyseniz, liste adı olur
skaler bir değişken.
Dinamik tip bağlama seçeneği C# 2010'da tanıtıldı. Bir değişken
dinamik ayrılmış dahil edilerek dinamik tür bağlama kullanmak için bildirilebilir
Aşağıdaki örnekte olduğu gibi, beyanında word:
dinamik herhangi;
Bu, herhangi birinin türe sahip olduğunu bildirmekten farklı olmasına rağmen benzerdir.
nesne . Herhangi birine herhangi bir türden bir değer atanabilmesi açısından benzerdir , tıpkı
nesne ilan edildiyse . Birkaç kişi için yararlı olmaması bakımından farklıdır.
farklı birlikte çalışma durumları; örneğin, dinamik olarak yazılmış
IronPython ve IronRuby gibi diller (Python'un .NET sürümleri ve
Ruby, sırasıyla). Ancak, bilinmeyen türden veriler geldiğinde yararlıdır.
harici bir kaynaktan bir programa Sınıf üyeleri, özellikler, yöntem
parametreler, yöntem dönüş değerleri ve yerel değişkenlerin tümü bildirilebilir
dinamik .
Saf nesne yönelimli dillerde - örneğin Ruby - tüm değişkenler
referanslar ve türleri yok; tüm veriler nesnelerdir ve herhangi bir değişken
herhangi bir nesneye başvurun. Bu tür dillerdeki değişkenler bir bakıma aynıdır.
type—bunlar referanslardır. Ancak, Java'daki referansların aksine,
belirli bir değer türüne atıfta bulunmakla sınırlı, Ruby'deki değişkenler
herhangi bir nesne.
Dinamik tip bağlamanın iki dezavantajı vardır. Birincisi, neden olur
programların daha az güvenilir olması, çünkü
derleyici, statik türe sahip bir dil için bir derleyiciye göre azalır
bağlamalar. Dinamik tip bağlama, herhangi bir değişkene bir değer atanmasına izin verir
her türden. Atamaların sağ taraflarının hatalı türleri algılanmaz
hatalar olarak; bunun yerine, sol tarafın türü basitçe yanlış olarak değiştirilir.
tip. Örneğin, belirli bir JavaScript programında i ve
x şu anda skaler sayısal değişkenlerin adlarıdır ve y şu anda
bir dizinin adı. Ayrıca, programın atamaya ihtiyacı olduğunu varsayalım.
açıklama

Sayfa 235
214
Bölüm 5 İsimler, Bağlar ve Kapsamlar
ben = x;
ancak bir anahtarlama hatası nedeniyle atama ifadesine sahiptir.
ben = y;
JavaScript'te (veya dinamik tür bağlama kullanan başka bir dilde), hata yok
bu ifadede yorumlayıcı tarafından algılanır—adlı değişkenin türü
i basitçe bir diziye değiştirilir. Ancak i'nin sonraki kullanımlarında bunun bir skaler olmasını bekleyeceğim,
ve doğru sonuçlar imkansız olacaktır. Statik tip bağlamaya sahip bir dilde,
Java gibi, derleyici i = y atamasındaki hatayı algılar ve
program çalıştırılmayacaktı.
Bu dezavantajın bazı dillerde bir dereceye kadar mevcut olduğunu unutmayın.
Fortran, C ve C++ gibi statik tip bağlama kullanan ve çoğu durumda otomatik olarak
bir atamanın RHS tipini otomatik olarak LHS tipine dönüştürün.
Dinamik tip bağlamanın belki de en büyük dezavantajı maliyettir. bu
dinamik öznitelik bağlamanın uygulanmasının maliyeti, özellikle
uygulama vakti. Çalışma zamanında tip kontrolü yapılmalıdır. Ayrıca, her
eğriyi korumak için değişken, kendisiyle ilişkilendirilmiş bir çalışma zamanı tanımlayıcısına sahip olmalıdır.
kira türü. Bir değişkenin değeri için kullanılan depolama, değişen boyutta olmalıdır,
çünkü farklı tür değerleri farklı miktarlarda depolama gerektirir.
Son olarak, değişkenler için dinamik tip bağlamaya sahip diller genellikle
derleyiciler yerine saf yorumlayıcılar kullanılarak uygulanır. bilgisayarlar
derleme zamanında işlenen türleri bilinmeyen talimatlara sahiptir. Orası-
bu nedenle, bir derleyici, A + B ifadesi için makine yönergeleri oluşturamaz.
A ve B türleri derleme zamanında bilinmiyor. Tipik olarak saf yorumlama
eşdeğer makine kodunu yürütmek için olduğundan en az 10 kat daha uzun sürer.
Tabii bir dil saf bir tercüman ile uygulanıyorsa, bunu yapmanın zamanı geldi.
dinamik tip bağlama, genel yorumlama süresi tarafından gizlenir, bu yüzden öyle görünüyor ki
bu ortamda daha az maliyetlidir. Öte yandan, statik türe sahip diller
bağlamalar nadiren saf yorumlama ile uygulanır, çünkü
bu diller kolaylıkla çok verimli makine kodu sürümlerine çevrilebilir.
5.4.3 Depolama Bağlantıları ve Kullanım Ömrü
Zorunlu bir programlama dilinin temel karakteri büyük
değişkenleri için depolama bağlamalarının tasarımı tarafından belirlenen kısım. Bu
bu nedenle, bu bağların net bir şekilde anlaşılması önemlidir.
Bir değişkenin bağlı olduğu bellek hücresi, bir şekilde
kullanılabilir bellek havuzu. Bu işleme tahsis denir . Serbest bırakma (şimdiki değeri)
bir değişkene bağlı olmayan bir bellek hücresi yerleştirme işlemi
kullanılabilir bellek havuzuna geri dönün.
Süresi bir değişken değişken bağlı olduğu zaman süresi olan
belirli bir bellek konumuna Böylece, bir değişkenin ömrü,
belirli bir hücreye bağlıdır ve o hücreden bağımsız olduğunda sona erer. İle
değişkenlerin depolama bağlarını araştırın, skaleri ayırmak uygundur

Sayfa 236
5.4 Bağlama Kavramı 215
(yapılandırılmamış) değişkenler ömürlerine göre dört kategoriye ayrılır. Bunlar
kategoriler statik, yığın dinamik, açık yığın dinamik ve örtük olarak adlandırılır.
yığın dinamik. Aşağıdaki bölümlerde, bu dördünün tanımlarını tartışacağız.
Kategoriler, amaçları, avantajları ve dezavantajları ile birlikte.
5.4.3.1 Statik Değişkenler
Statik değişkenler , program yürütülmeden önce bellek hücrelerine bağlı olanlardır.
başlar ve program yürütülene kadar aynı bellek hücrelerine bağlı kalır.
sona erer. Statik olarak bağlı değişkenlerin birçok değerli uygulaması vardır.
programlama. Genel olarak erişilebilir değişkenler genellikle yürütme boyunca kullanılır.
bir programın oluşturulması, böylece onların aynı programa bağlanmasını gerekli kılar.
Bu yürütme sırasında depolama. Bazen alt programlara sahip olmak uygundur
tarihe duyarlı olanlar. Böyle bir alt program yerel statik değişkenlere sahip olmalıdır.
Statik değişkenlerin bir avantajı verimliliktir. Tüm statik değişken adreslemeleri
mümkünler doğrudan olabilir; Diğer 5 tür değişken genellikle dolaylı adresleme gerektirir,
hangisi daha yavaş. Ayrıca, tahsis ve işlem için çalışma zamanı ek yükü oluşmaz.
statik değişkenlerin konumu, ancak bu süre genellikle ihmal edilebilir.
Depolamaya statik bağlanmanın bir dezavantajı azaltılmış esnekliktir; içinde
özellikle, yalnızca statik değişkenlere sahip bir dil özyinelemeyi destekleyemez.
alt programlar. Diğer bir dezavantaj, depolamanın aralarında paylaşılamamasıdır.
değişkenler. Örneğin, bir programın iki alt programı olduğunu varsayalım.
büyük diziler gerektirir. Ayrıca, iki alt programın hiçbir zaman
aynı anda aktif. Diziler statik ise, aynı depoyu paylaşamazlar.
dizileri için yaş.
C ve C++, programcıların bir değişkene statik belirteci eklemesine izin verir.
tanımladığı değişkenleri statik hale getirerek bir fonksiyonda tanımlayabilme. Bunu not et
ne zaman statik değiştirici bir sınıfta bir değişken bildiriminde yer alan
C++, Java ve C#'daki tanım, aynı zamanda değişkenin bir sınıf değişkeni olduğu anlamına gelir.
bir örnek değişkeni yerine mümkün. Sınıf değişkenleri statik olarak oluşturulur.
sınıfın ilk somutlaştırılmasından önceki süre.
5.4.3.2 Yığın Dinamik Değişkenleri
Yığın dinamik değişkenleri , depolama bağlamaları oluşturulduğunda oluşturulanlardır.
bildirim ifadeleri ayrıntılıdır, ancak türleri statik olarak
ciltli. Böyle bir beyanın detaylandırılması , depolama tahsisine atıfta bulunur ve
Yürütme sırasında gerçekleşen, beyanname ile belirtilen bağlayıcı süreç
beyannamenin eklendiği koda ulaşır. Bu nedenle, detaylandırma
çalışma süresi sırasında oluşur. Örneğin, görünen değişken bildirimleri
Java yönteminin başlangıcı, yöntem çağrıldığında detaylandırılır ve
Bu bildirimler tarafından tanımlanan değişkenler, yöntem kullanıldığında serbest bırakılır.
yürütmesini tamamlar.
5. Bazı uygulamalarda, statik değişkenler bir temel kayıt aracılığıyla adreslenir,
bunlara erişim, yığınla ayrılmış değişkenler kadar maliyetlidir.

Sayfa 237
216
Bölüm 5 İsimler, Bağlar ve Kapsamlar
Adlarından da anlaşılacağı gibi, yığın dinamik değişkenleri
çalışma zamanı yığını.
Bazı diller (örneğin, C++ ve Java) değişken bildirimlerine izin verir
bir ifadenin görünebileceği her yerde meydana gelmesi. Bunların bazı uygulamalarında
diller, bir işlev veya yöntemde bildirilen tüm yığın dinamik değişkenleri
(iç içe bloklarda bildirilenler hariç)
bildirilmesine rağmen, işlevin veya yöntemin yürütülmesinin başlangıcı
Bu değişkenlerden bazılarının tionları başlangıçta görünmez. Bu gibi durumlarda,
değişken bildirimde görünür hale gelir, ancak depolama bağlaması (ve
başlatma, bildirimde belirtilmişse), işlev veya
yöntem yürütmeye başlar. Bir değişkenin depolama bağlamasının gerçekleştiği gerçeği
görünür hale gelmeden önce dilin anlamını etkilemez.
Yığın dinamik değişkenlerin avantajları aşağıdaki gibidir:
en azından çoğu durumda, özyinelemeli alt programlar bir tür dinamik yerel
özyinelemeli alt programın her aktif kopyasının kendi sürümüne sahip olması için depolama
yerel değişkenler. Bu ihtiyaçlar yığın dinamiği ile rahatlıkla karşılanır.
değişkenler. Özyineleme olmadığında bile, yığın dinamik yerel depolamaya sahip olmak
alt programlar için değersiz değildir, çünkü tüm alt programlar aynı
yerlileri için hafıza alanı.
Statik değişkenlere göre yığın dinamik değişkenlerin dezavantajları
tahsis ve tahsisin çalışma zamanı yükü, muhtemelen daha yavaş
dolaylı adresleme gerektiğinden ve alt programların
tarihe duyarlı olamaz. Yığın tahsisi ve yeniden tahsisi için gereken süre
dinamik değişkenler önemli değildir, çünkü yığın dinamik değişkenlerin tümü
Bir alt programın başında beyan edilenler tahsis edilir ve dağıtılır.
ayrı operasyonlar yerine birlikte.
Fortran 95+, uygulayıcıların yereller için yığın dinamik değişkenleri kullanmasına izin verir,
ancak aşağıdaki ifadeyi içerir:
Listeyi kaydet
Bu bildirim, programcının değişkenlerin bir kısmının veya tamamının
ables hangi alt programında (listede olanlar) Kaydet statik olacaktır yerleştirilir.
Java, C++ ve C#'da yöntemlerde tanımlanan değişkenler varsayılan olarak yığındır
dinamik. Ada'da, alt programlarda tanımlanan tüm yığın olmayan değişkenler yığın dinamiktir.
Depolama dışındaki tüm nitelikler statik olarak yığın dinamiğine bağlıdır
skaler değişkenler. Tartışıldığı gibi, bazı yapılandırılmış türler için durum böyle değildir.
Bölüm 6. Yığın için tahsis/tahsis süreçlerinin uygulanması
dinamik değişkenler Bölüm 10'da tartışılmaktadır.
5.4.3.3 Açık Yığın Dinamik Değişkenleri
Açık yığın dinamik değişkenler , adsız (soyut) bellek hücreleridir.
tarafından yazılan açık çalışma zamanı talimatları tarafından tahsis edilir ve tahsis edilmez.
gramer. Heap'ten tahsis edilen ve heap'e tahsis edilen bu değişkenler,
yalnızca işaretçi veya referans değişkenleri aracılığıyla başvurulabilir. Yığın bir kol-
nedeniyle organizasyonu oldukça düzensiz olan depolama hücrelerinin seçimi

Sayfa 238
5.4 Bağlama Kavramı 217
kullanımının öngörülemezliği. Erişmek için kullanılan işaretçi veya başvuru değişkeni
açık bir yığın dinamik değişkeni, diğer herhangi bir skaler değişken olarak oluşturulur. açık bir
yığın dinamik değişkeni, bir operatör (örneğin, C++'da) veya bir
bu amaç için sağlanan bir sistem alt programına çağrı (örneğin, C'de).
C++'da, new adlı ayırma operatörü, tür adı olarak bir tür adı kullanır.
işlenen. Yürütüldüğünde, işlenenin açık bir yığın dinamik değişkeni
type oluşturulur ve adresi döndürülür. Çünkü açık bir yığın dinamik
değişken, derleme zamanında bir türe bağlanır, bu bağlama statiktir. Ancak,
bu tür değişkenler, oluşturuldukları anda depolamaya bağlıdır;
çalışma süresi boyunca.
Açık yığın dinamiği oluşturmak için bir alt programa veya operatöre ek olarak
değişkenler, bazı diller açıkça için bir alt program veya operatör içerir
onları yok etmek.
Açık yığın dinamik değişkenlere bir örnek olarak, aşağıdakileri göz önünde bulundurun
C++ kod segmenti:
int *iç düğüm; // Bir işaretçi oluştur
intnode = yeni int; // yığın dinamik değişkeni oluşturun
. . .
intnode'u sil ; // Yığın dinamik değişkenini serbest bırakın
// hangi intnode'un işaret ettiği
Bu örnekte, int türünde açık bir yığın dinamik değişkeni tarafından oluşturulur.
Yeni operatör. Bu değişkene daha sonra işaretçi aracılığıyla başvurulabilir,
iç düğüm . Daha sonra değişken, silme operatörü tarafından serbest bırakılır . C++
açık ayırma operatörünü silme gerektirir , çünkü kullanmaz
çöp toplama gibi örtük depolama ıslahı.
Java'da ilkel skalerler dışındaki tüm veriler nesnelerdir. Java nesneleri
açıkça yığın dinamiktir ve referans değişkenler aracılığıyla erişilir. Java'nın sahip olduğu
yığın dinamik değişkeni açıkça yok etmenin hiçbir yolu yoktur; daha ziyade, örtük gar-
bage koleksiyonu kullanılır. Çöp toplama, Bölüm 6'da tartışılmaktadır.
C# açık yığın dinamik ve yığın dinamik nesnelere sahiptir ve bunların tümü
dolaylı olarak serbest bırakılır. Ayrıca C#, C++ tarzı işaretçileri destekler. Çok
işaretçiler yığın, yığın ve hatta statik değişkenlere ve nesnelere başvurmak için kullanılır.
Bu işaretçiler, C++ ile aynı tehlikelere ve kullandıkları nesnelere sahiptir.
yığın üzerindeki referans örtük olarak serbest bırakılmaz. İşaretçiler dahildir
C# bileşenlerinin C ve C++ bileşenleriyle birlikte çalışmasına izin vermek için C#. İle
kullanımlarını caydırmak ve ayrıca herhangi bir program okuyucusuna kodun
işaretçileri kullanır, bir işaretçiyi tanımlayan herhangi bir yöntemin başlığı şunları içermelidir:
ayrılmış kelime güvensiz .
Açık yığın dinamik değişkenleri genellikle dinamik yapı oluşturmak için kullanılır.
sırasında büyümesi ve/veya küçülmesi gereken bağlantılı listeler ve ağaçlar gibi
uygulamak. Bu tür yapılar, işaretçiler veya referanslar kullanılarak uygun bir şekilde oluşturulabilir.
ences ve açık yığın dinamik değişkenler.
Açık yığın dinamik değişkenlerin dezavantajları,
işaretçi ve referans değişkenlerini doğru bir şekilde kullanarak, referanslara yapılan referansların maliyeti

Sayfa 239
218
Bölüm 5 İsimler, Bağlar ve Kapsamlar
değişkenler ve gerekli depolama yönetimi uygulamasının karmaşıklığı
tion. Bu aslında maliyetli ve maliyetli olan yığın yönetimi sorunudur.
karmaşık. Açık yığın dinamik değişkenler için uygulama yöntemleri şunlardır:
Bölüm 6'da uzun uzun tartışılmıştır.
5.4.3.4 Örtülü Yığın Dinamik Değişkenleri
Örtülü yığın dinamik değişkenleri , yalnızca şu durumlarda yığın depolamaya bağlıdır:
atanan değerlerdir. Aslında, tüm nitelikleri her seferinde bağlıdır
atanırlar. Örneğin, aşağıdaki JavaScript atamasını göz önünde bulundurun
Beyan:
yüksekler = [74, 84, 86, 90, 71];
highs adlı değişkenin daha önce
programı veya ne için kullanıldığı, şimdi beş sayısal değerden oluşan bir dizidir.
Bu tür değişkenlerin avantajı, en yüksek dereceye sahip olmalarıdır.
esneklik, son derece genel kodun yazılmasına izin verir. Bir dezavantajı
örtük yığın dinamik değişkenler, tümünü korumanın çalışma zamanı yüküdür.
dizi alt simge türleri ve aralıklarını içerebilen dinamik nitelikler,
diğerleri arasında. Diğer bir dezavantaj, sistem tarafından bazı hata tespitlerinin kaybedilmesidir.
derleyici, Bölüm 5.4.2.2'de tartışıldığı gibi. Örtülü yığın dinamiği örnekleri
JavaScript'teki değişkenler Bölüm 5.4.2.2'de görünmektedir.
5.5 Kapsam e
Değişkenleri anlamada önemli faktörlerden biri kapsamdır. kapsamı içinde
değişken, değişkenin görünür olduğu ifadeler aralığıdır. Bir değişken
olduğu görünür o açıklamada başvurulan edilebilirse açıklamada.
Bir dilin kapsam kuralları, bir dilin belirli bir oluşumunun nasıl olduğunu belirler.
name bir değişkenle ilişkilendirilir veya işlevsel bir dil söz konusu olduğunda, nasıl
bir isim bir ifadeyle ilişkilendirilir. Özellikle kapsam kuralları,
o anda yürütülmekte olan alt programın dışında bildirilen değişkenlere yapılan başvuruların nasıl
gram veya blok, bildirimleriyle ve dolayısıyla nitelikleriyle ilişkilidir.
(bloklar Bölüm 5.5.2'de tartışılmıştır). Bu kuralların net bir şekilde anlaşılması
bu nedenle bir dil için program yazma veya okuma yeteneği için gereklidir
o dilde.
Bir değişken, orada bildirilmişse, bir program biriminde veya blokta yereldir .
Bir program biriminin veya bloğunun yerel olmayan değişkenleri, görünür olanlardır.
program birimi veya bloğu içinde ible ancak orada bildirilmez. küresel
değişkenler, yerel olmayan değişkenlerin özel bir kategorisidir. Onlar tartışılır
Bölüm 5.5.4.
Sınıfların, paketlerin ve ad alanlarının kapsam belirleme sorunları şu bölümde tartışılmaktadır:
Bölüm 11.

Sayfa 240
5.5 Kapsam
219
5.5.1 Statik Kapsam
ALGOL 60, yerel olmayan değişkenlere ad bağlama yöntemini tanıttı
statik kapsam olarak adlandırılan , sonraki birçok emir tarafından kopyalanan 6
diller ve birçok zorunlu olmayan diller de. Statik kapsam belirleme
adlandırılmıştır çünkü bir değişkenin kapsamı statik olarak belirlenebilir; yani,
yürütmeden önce. Bu, bir insan program okuyucusunun (ve bir derleyicinin)
programdaki her değişkenin türünü basitçe inceleyerek belirleyin.
kaynak kodu.
Statik kapsamlı dillerin iki kategorisi vardır: alt-
programlar iç içe yerleştirilebilir, bu da iç içe statik kapsamlar oluşturur ve bunların içinde
alt programlar yuvalanamaz. İkinci kategoride, statik kapsamlar da
alt programlar tarafından oluşturulur, ancak iç içe kapsamlar yalnızca iç içe sınıf tarafından oluşturulur
tanımlar ve bloklar.
Ada, JavaScript, Common LISP, Scheme, Fortran 2003+, F# ve Python
iç içe alt programlara izin verir, ancak C tabanlı diller vermez.
Bu bölümdeki statik kapsam belirleme tartışmamız bu alanlara odaklanmaktadır.
iç içe alt programlara izin veren göstergeler. Başlangıçta, tüm kapsamların
program birimleriyle ilişkili ve başvurulan tüm yerel olmayan değişkenler
diğer program birimlerinde ilan edilir. 7 Bu bölümde, kapsam belirlemenin
altındaki dillerde yerel olmayan değişkenlere erişmenin tek yöntemidir.
tartışma. Bu, tüm diller için geçerli değildir. Hatta tüm lan-
statik kapsam kullanan göstergeler, ancak varsayım tartışmayı basitleştirir
burada.
Bir programın okuyucusu bir değişkene referans bulduğunda, özellik
değişkenin değerleri, içinde bulunduğu ifade bulunarak belirlenebilir.
(açıkça veya zımnen) beyan edilmiştir. Statik kapsamlı dillerde iç içe
alt programlarda bu işlem şu şekilde düşünülebilir. Bir
sub1 alt programında bir x değişkenine referans yapılır . Doğru beyan-
İlk olarak sub1 alt programının bildirimleri aranarak bulunur . Eğer hayırsa
oradaki değişken için bildirim bulunur, arama bildirimde devam eder.
olarak adlandırılan alt programı sub1 bildiren alt programın
statik ebeveyn . Orada bir x bildirimi bulunamazsa, arama devam eder.
sonraki daha büyük çevreleyen birim ( sub1'in ebeveynini bildiren birim ) ve böylece
ileri, x için bir bildirim bulunana veya en büyük birimin bildirimleri bulunana kadar
başarı olmadan arandı. Bu durumda, bildirilmemiş bir değişken hatası
bildirildi. sub1 alt programının statik ebeveyni ve statik ebeveyni ve
en büyük çevreleyen alt programa kadar ve buna dahil olarak, denir
Statik ataları arasında sub1 . Statik kapsam için gerçek uygulama teknikleri
Bölüm 10'da tartışılan, genellikle aşağıdakilerden çok daha verimlidir.
az önce açıklanan süreç.
6. Statik kapsam belirlemeye bazen sözcüksel kapsam belirleme denir .
7. Diğer program birimlerinde tanımlanmayan yerel olmayan değişkenler Bölüm 5.5.4'te tartışılmaktadır.

Sayfa 241
220
Bölüm 5 İsimler, Bağlar ve Kapsamlar
Aşağıdaki JavaScript işlevini göz önünde bulundurun, büyük , iki işlevin
ları abon1 ve sub2 yuvalanmış:
fonksiyon büyük() {
işlev alt1() {
var x = 7;
alt2();
}
işlev alt2() {
var y = x;
}
var x = 3;
alt1();
}
Statik Kapsama alma altında, değişken referans x içinde sub2 etmektir x ilan
prosedürde büyük . Bu doğrudur çünkü x arayışı pro-
başvurunun gerçekleştiği sedur , sub2 , ancak x için hiçbir bildirim bulunamadı
orada. Arama, sub2 , big öğesinin statik ebeveyninde devam eder , burada dec-
x larasyonu bulunur. X beyan sub1 o olmadığı için, göz ardı edilir
sub2'nin statik atası .
İç içe geçmiş olup olmadığına bakılmaksızın statik kapsam kullanan bazı dillerde
alt programlara izin verilir, bazı değişken bildirimleri bazı programlardan gizlenebilir.
diğer kod bölümleri. Örneğin, büyük JavaScript işlevini tekrar düşünün .
Değişken x hem de bildirilmiş Büyük ve sub1 iç içe içeride olan büyük .
sub1 içinde , x'e yapılan her basit referans , yerel x'e yapılır . Bu nedenle, dış
x , sub1 öğesinden gizlenir .
Ada'da, ata kapsamlarından gelen gizli değişkenlere seçimle erişilebilir.
ata kapsamının adını içeren referanslar. Örneğin, eğer bizim
önceki örnek fonksiyon büyük Ada'da yazılmıştı, x büyük olarak bildirildi
erişilebilir olabilir sub1 referans ile big.x .
5.5.2 Bloklar
Birçok dil, yürütmenin ortasında yeni statik kapsamların tanımlanmasına izin verir.
mümkün kod. ALGOL 60'ta tanıtılan bu güçlü konsept,
kapsamı en aza indirilmiş kendi yerel değişkenlerine sahip olmak için kodun. Bu tür değişken-
yetenekler tipik olarak yığın dinamiktir, bu nedenle depolamaları bölüm
bölümden çıkıldığında girilir ve serbest bırakılır. Böyle bir kod bölümü
blok denir . Bloklar, blok ifadesinin kökenini sağlar - yapılandırılmış
dil .
C tabanlı diller, herhangi bir bileşik ifadeye izin verir (bir ifade
eşleşen parantezlerle çevrili dizi) bildirimlere sahip olmak ve böylece
yeni bir kapsam tanımlayın. Bu tür bileşik ifadelere blok denir. Örneğin,
liste bir tamsayı dizisi olsaydı , yazılabilirdi

Sayfa 242
5.5 Kapsam
221
if (list[i] < liste[j]) {
int sıcaklık;
sıcaklık = liste[i];
liste[i] = liste[j];
liste[j] = sıcaklık;
}
Daha büyük bloklarda yuvalanabilen bloklar tarafından oluşturulan kapsamlar,
tam olarak alt programlar tarafından oluşturulanlar gibi ele alınır. çeşitli referanslar
orada bildirilmeyen bir bloktaki yetenekler, bildirimlere şu şekilde bağlanır:
artan sırayla çevreleyen kapsamları (bloklar veya alt programlar) aramak
boyut.
Aşağıdaki iskelet C fonksiyonunu göz önünde bulundurun:
geçersiz alt() {
int sayısı;
. . .
süre (. . .) {
int sayısı;
say++;
. . .
}
. . .
}
Referans saymak içinde iken döngü o döngüsünün yerel etmektir sayım . İçinde
Bu durumda, sayım ve alt iç kodundan gizlidir iken döngü. İçinde
Genel olarak, bir değişken için bir bildirim, bir değişkenin herhangi bir bildirimini etkin bir şekilde gizler.
daha büyük bir kapsama alanında aynı adla mümkün. 8 Bu kodun
C ve C++'da yasal ancak Java ve C#'da yasa dışıdır. Java ve C# tasarımcıları
isimlerin iç içe bloklarda yeniden kullanılmasının hataya çok açık olduğuna inanıyordu.
izin verilmiş.
JavaScript, iç içe işlevleri için statik kapsam belirleme kullansa da,
fonksiyon blokları dilde tanımlanamaz.
Çoğu işlevsel programlama dili, ilgili bir yapı içerir.
genellikle let olarak adlandırılan zorunlu dillerin bloklarına . Bu yapılar
adları genellikle şu şekilde belirtilen değerlere bağlamak olan iki bölümden oluşur.
ifade. İkinci kısım, içinde tanımlanan adları kullanan bir ifadedir.
ilk kısım. İşlevsel dillerdeki programlar ifadelerden oluşur.
ifadelerden daha fazla. Bu nedenle, let yapısının son kısmı bir ifadedir,
8. Bölüm 5.5.4'te tartışıldığı gibi, C++'da bu tür gizli global değişkenlere
kapsam operatörünü kullanarak iç kapsam ( :: ).

Sayfa 243
222
Bölüm 5 İsimler, Bağlar ve Kapsamlar
bir açıklamadan ziyade. Şemada, let yapısı LET işlevine yapılan bir çağrıdır.
aşağıdaki formla:
(İZİN VERMEK (
( isim 1 ifade 1 )
. . .
( isim n ifade n ))
ifade
)
LET çağrısının semantiği aşağıdaki gibidir: İlk n ifadeler
değerlendirilir ve değerler ilişkili adlara atanır. Ardından, final
ifade değerlendirilir ve LET'in dönüş değeri bu değerdir. Bu farklıdır
adların değerlere sahip olması bakımından zorunlu bir dilde bir bloktan; onlar
zorunluluk anlamında değişkenler değildir. Bir kez ayarlandıktan sonra değiştirilemezler.
Ancak, bir emir dilinde bir bloktaki yerel değişkenler gibidirler.
kapsamlarının LET çağrısına yerel olduğunu . LET için aşağıdaki çağrıyı göz önünde bulundurun :
(İZİN VERMEK (
(üst (+ ab))
(alt (- cd)))
(/ üst alt)
)
Bu çağrı (a + b) / (c – d) ifadesinin değerini hesaplar ve döndürür .
ML'de let yapısının formu aşağıdaki gibidir:
İzin Vermek
val adı 1 = ifade 1
. . .
val adı n = ifade n
içinde
ifade
son ;
Her val ifadesi, bir ifadeye bir isim bağlar. Şemada olduğu gibi,
ilk kısımdaki isimler, emir kipi dillerinin adlandırılmış sabitleri gibidir;
ayarlandıktan sonra değiştirilemezler. 9 Aşağıdaki let yapısını göz önünde bulundurun :
İzin Vermek
val En = a + b
val alt = c - d
içinde
üst / alt
son;
9. Bölüm 15'te bunların sıfırlanabileceğini, ancak sürecin aslında yeni bir şey oluşturduğunu göreceğiz.
isim.

Sayfa 244
5.5 Kapsam
223
F#'da let yapısının genel biçimi şu şekildedir:
left_side = ifadeye izin ver
let öğesinin left_side'ı bir ad veya bir demet deseni (bir ad dizisi) olabilir.
virgüllerle ayrılmış).
Bir fonksiyon tanımı içinde let ile tanımlanan bir ismin kapsamı
tanımlayıcı ifadenin sonu, işlevin sonuna. izin kapsamı
yeni bir yerel kapsam oluşturan aşağıdaki kodu girintileyerek sınırlanabilir.
Herhangi bir girinti işe yarayacak olsa da, kural, girintinin
dört boşluk. Aşağıdaki kodu göz önünde bulundurun:
let n1 =
let n2 = 7
izin 3 = n2 + 3
n3;;
izin 4 = n-3 + n 1 ;;
n1'in kapsamı tüm kodu kapsar. Ancak, n2'nin kapsamı ve
n3 , girinti sona erdiğinde biter. Yani, kullanımı n3 sonuncu let bir sebep
hata. Son satır let n1 kapsamına bağlı değerdir n1 ; olabilir
herhangi bir ifade.
Bölüm 15, Scheme, ML'deki let yapılarının daha fazla ayrıntısını içerir,
Haskell ve F#.
5.5.3 Beyanname Sırası
C89'da ve diğer bazı dillerde, bir fonksiyondaki tüm veri bildirimleri
ancak iç içe bloklardakiler işlevin başında görünmelidir.
Ancak bazı diller—örneğin, C99, C++, Java, JavaScript ve
C#—bir ifadenin görünebileceği her yerde değişken bildirimlerinin görünmesine izin verir
bir program biriminde Bildirimler, ilişkili olmayan kapsamlar oluşturabilir
bileşik ifadeler veya alt programlar ile. Örneğin, C99, C++ ve
Java, tüm yerel değişkenlerin kapsamı, bildirimlerinden sonuna kadardır.
bu bildirimlerin göründüğü bloklar. Ancak, C#'ta kapsamı
bir blokta bildirilen herhangi bir değişken, konumdan bağımsız olarak tüm bloktur.
iç içe bir blokta olmadığı sürece, bildirimin blokta bulunması.
Aynı şey yöntemler için de geçerlidir. C#'ın hala tüm değişkenlerin
kullanılmadan önce bildirilmelidir. Bu nedenle, her ne kadar bir değişkenin kapsamı-
bildirimden bloğun veya alt programın en üstüne kadar uzanır.
bu bildirim göründüğünde, değişken hala kendi değerinin üzerinde kullanılamaz.
beyanname.
JavaScript'te yerel değişkenler bir fonksiyonun herhangi bir yerinde bildirilebilir.
ancak böyle bir değişkenin kapsamı her zaman fonksiyonun tamamıdır. Daha önce kullanılmışsa
fonksiyondaki bildirimi, böyle bir değişken undefined değerine sahiptir .

Sayfa 245
224
Bölüm 5 İsimler, Bağlar ve Kapsamlar
C++, Java ve C#' ın for deyimleri, değişken tanımlarına izin verir.
başlatma ifadeleri. C++'ın ilk sürümlerinde, böyle bir
değişken, tanımından en küçük çevreleyen bloğun sonuna kadardı. İçinde
standart sürüm, ancak kapsam, for yapısıyla sınırlıdır , çünkü
Java ve C# ile durum böyledir. Aşağıdaki iskelet yöntemini göz önünde bulundurun:
boş eğlence() {
. . .
for ( int sayı = 0; sayı < 10; sayı++){
. . .
}
. . .
}
Yanı sıra Java ve C # C ++ sonraki sürümlerinde, olarak, kapsamı sayımı dan
için vücudunun sonuna açıklamada.
5.5.4 Küresel Kapsam
C, C++, PHP, JavaScript ve Python dahil olmak üzere bazı diller,
değişkenlerin olduğu bir dizi fonksiyon tanımları olan program yapısı.
mümkün tanımlar fonksiyonların dışında görünebilir. Fonksiyon dışındaki tanımlar
Bir dosyadaki tionlar, potansiyel olarak bu kişiler tarafından görülebilen global değişkenler yaratır.
fonksiyonlar.
C ve C++, küresel verilerin hem bildirimlerine hem de tanımlarına sahiptir. deklara-
türleri ve diğer nitelikleri belirtir, ancak depolama tahsisine neden olmaz.
Tanımlar nitelikleri belirtir ve depolama tahsisine neden olur. Belirli bir küresel
ad, bir C programı herhangi bir sayıda uyumlu bildirime sahip olabilir, ancak yalnızca
tek bir tanım.
İşlev tanımlarının dışında bir değişkenin bildirimi,
değişken farklı bir dosyada tanımlanmış. C'deki global bir değişken örtük olarak görünür
bir bildirim içerenler hariç, dosyadaki sonraki tüm işlevlerde
aynı ada sahip yerel bir değişkenin Bir değişkenden sonra tanımlanan global bir değişken
işlev, dış olduğu bildirilerek işlevde görünür hale getirilebilir.
aşağıdakilerde:
dış int toplamı;
C99'da, global değişkenlerin tanımları genellikle başlangıç ​​değerlerine sahiptir. beyannameler
global değişkenlerin hiçbir zaman başlangıç ​​değerleri yoktur. Bildirim fonksiyonun dışındaysa
tanımlar için, extern niteleyicisini içermesi gerekmez .
Bu bildirimler ve tanımlar fikri, işlevlere taşınır.
Prototiplerin işlevlerin adlarını ve arabirimlerini bildirdiği C ve C++
ancak kodlarını vermeyin. Fonksiyon tanımları ise,
tamamlayınız.

Sayfa 246
5.5 Kapsam
225
C++'da, aynı ada sahip bir yerel tarafından gizlenen global bir değişken,
kapsam operatörü ( :: ) kullanılarak erişilebilir . Örneğin, x bir global ise, bu
x adında bir yerel tarafından bir işlevde gizlenmişse , global ::x olarak adlandırılabilir .
PHP ifadeleri, işlev tanımları ile serpiştirilebilir. Değişkenler
PHP'de ifadelerde göründüklerinde örtük olarak bildirilir. herhangi bir değişken
herhangi bir fonksiyonun dışında dolaylı olarak bildirilen bu, global bir değişkendir; değişkenler
fonksiyonlarda örtük olarak bildirilenler yerel değişkenlerdir. Küresel değişkenlerin kapsamı
bildirimlerinden programın sonuna kadar uzanır, ancak herhangi birini atlar.
sonraki fonksiyon tanımları. Bu nedenle, global değişkenler örtük olarak görünür değildir
herhangi bir işlevde. Global değişkenler, kapsamlarındaki fonksiyonlarda görünür hale getirilebilir
iki şekilde: (1) İşlev aynı ada sahip yerel bir değişken içeriyorsa
global olarak, bu global'e $GLOBALS dizisi aracılığıyla erişilebilir.
dizge değişmez alt simgesi olarak globalin adı ve (2) yerel yoksa
global ile aynı ada sahip fonksiyondaki değişken, global olabilir
küresel bir beyan beyanına dahil edilerek görünür kılınmıştır . Yi hesaba kat
aşağıdaki örnek:
$gün = "Pazartesi";
$ay = "Ocak";
işlev takvimi() {
$gün = "Salı";
küresel $ay;
print "yerel gün $gündür <br />";
$gday = $KÜRESEL['gün'];
print "küresel gün $gday <br \>";
print "küresel ay $aydır <br />";
}
takvim();
Bu kodun yorumlanması aşağıdakileri üretir:
yerel gün Salı
dünya günü pazartesi
küresel ay Ocak
JavaScript'in global değişkenleri, PHP'ninkilere çok benzer;
bildiren bir fonksiyonda global bir değişkene erişmenin bir yolu yoktur.
aynı ada sahip yerel değişken.
Python'da global değişkenler için görünürlük kuralları olağandışıdır. Değişkenler
PHP'de olduğu gibi normalde bildirilmez. Ne zaman örtülü olarak ilan edilirler
atama ifadelerinin hedefleri olarak görünür. Global bir değişken referans olabilir.
bir işlevde bulunur, ancak yalnızca bir işlevde global bir değişken atanabilir

Sayfa 247
226
Bölüm 5 İsimler, Bağlar ve Kapsamlar
fonksiyonda global olarak bildirilmişse. Aşağıdakileri göz önünde bulundur
örnekler:
gün = "Pazartesi"
def tester():
print "Dünya günü:", gün
test cihazı()
Bu betiğin çıktısı, çünkü globallere doğrudan işlevde başvurulabilir.
ler, aşağıdaki gibidir:
Küresel gün: Pazartesi
Aşağıdaki komut dosyası, global güne yeni bir değer atamaya çalışır :
gün = "Pazartesi"
def tester():
print "Dünya günü:", gün
gün = "Salı"
print "Günün yeni değeri:", gün
test cihazı()
Bu komut dosyası bir UnboundLocalError hata mesajı oluşturur , çünkü
işlevin gövdesinin ikinci satırında güne atama günü a yapar
gövdesinin ilk satırında güne referans yapan yerel değişken
işlev, yerele geçersiz bir ileri başvuru.
İçin atama gününde ise küresel değişkene olabilir gün ilan edilir
fonksiyonun başında global olun. Bu, güne atamayı önler
yerel bir değişken oluşturmaktan. Bu, aşağıdaki komut dosyasında gösterilir:
gün = "Pazartesi"
def tester():
dünya günü
print "Dünya günü:", gün
gün = "Salı"
print "Günün yeni değeri:", gün
test cihazı()
Bu betiğin çıktısı aşağıdaki gibidir:
Küresel gün: Pazartesi
Günün yeni değeri: Salı

Sayfa 248
5.5 Kapsam
227
İşlevler Python'da iç içe olabilir. Yuvalama işlevlerinde tanımlanan değişkenler
Statik kapsam yoluyla iç içe bir işlevde erişilebilir, ancak bu tür değişkenler
iç içe işlevde yerel olmayan olarak bildirilmelidir . 10 Örnek bir iskelet pro-
Bölüm 5.7'deki gram, yerel olmayan değişkenlere erişimleri gösterir.
F#'da fonksiyon tanımlarının dışında tanımlanan tüm isimler globaldir. Onların
kapsam, tanımlarından dosyanın sonuna kadar uzanır.
Bildirim sırası ve global değişkenler de sınıftaki sorunlardır ve
nesne yönelimli dillerde üye bildirimleri. bunlar şurada tartışılıyor
Bölüm 12.
5.5.5 Statik Kapsamın Değerlendirilmesi
Statik kapsam belirleme, birçok durumda iyi çalışan yerel olmayan bir erişim yöntemi sağlar.
durumlar. Ancak, sorunları olmadan değildir. İlk olarak, çoğu durumda izin verir
hem değişkenlere hem de alt programlara gerekenden daha fazla erişim. bu basitçe
bu tür kısıtlamaları kısaca belirtmek için çok kaba bir araç. İkincisi ve belki
daha da önemlisi, program evrimiyle ilgili bir problemdir. Yazılım son derece
dinamik—düzenli olarak kullanılan programlar sürekli değişir. Bu değişiklikler
genellikle yeniden yapılanmayla sonuçlanır, böylece ilk yapıyı yok eder.
kısıtlı değişken ve alt program erişimi. Bakımın karmaşıklığından kaçınmak için-
Bu erişim kısıtlamalarını göz önünde bulundurarak, geliştiriciler genellikle içeri girdiğinde yapıyı atarlar.
yol. Bu nedenle, statik kapsam belirleme kısıtlamalarını aşmak,
alanlarda bile orijinaline çok az benzerlik gösteren program tasarımları
değişiklik yapılmayan program. Tasarımcılar teşvik ediliyor
gerekenden çok daha fazla global kullanmak. Tüm alt programlar
aynı seviyede, ana programda, daha derin yerine küreseller kullanılarak iç içe
yuvalama seviyeleri. 11 Ayrıca, nihai tasarım garip ve yapmacık olabilir,
ve temeldeki kavramsal tasarımı yansıtmayabilir. Bunlar ve diğerleri
statik kapsam belirlemenin kusurları Clarke, Wileden ve Wolf'ta ayrıntılı olarak tartışılmaktadır.
(1980). Değişkenlere erişimi kontrol etmek için statik kapsam kullanımına bir alternatif
ve alt programlar, birçok programa dahil olan bir kapsülleme yapısıdır.
daha yeni diller. Kapsülleme yapıları Bölüm 11'de tartışılmaktadır.
5.5.6 Dinamik Kapsam
APL, SNOBOL4 ve LISP'nin ilk sürümlerindeki değişkenlerin kapsamı şu şekildedir:
dinamik. Perl ve Common LISP ayrıca değişkenlerin sahip olduklarının bildirilmesine izin verir.
dinamik kapsam, ancak bu dillerdeki varsayılan kapsam belirleme mekanizması
statik. Dinamik kapsam belirleme , alt programların çağrı sırasına dayalıdır,
birbirleriyle uzamsal ilişkileri üzerine. Böylece kapsam belirlenebilir
sadece çalışma zamanında.
10. Yerel olmayan ayrılmış sözcük Python 3'te tanıtıldı.
11. Kulağa bir C programının yapısı gibi geliyor, değil mi?

Sayfa 249
228
Bölüm 5 İsimler, Bağlar ve Kapsamlar
Yeniden oluşturulan Bölüm 5.5.1'deki büyük işlevi tekrar düşünün.
burada, eksi işlev çağrıları:
fonksiyon büyük() {
işlev alt1() {
var x = 7;
}
işlev alt2() {
var y = x;
var z = 3;
}
var x = 3;
}
Dinamik kapsam belirleme kurallarının yerel olmayan başvurular için geçerli olduğunu varsayın. Anlam
sub2'de başvurulan x tanımlayıcısının dinamiktir—belirlenemez
derleme zamanında. Değişkene x bildiriminden herhangi birine başvurabilir ,
arama sırasına bağlı olarak.
Yürütme sırasında x'in doğru anlamının belirlenebilmesinin bir yolu şudur:
yerel bildirimlerle aramaya başlamak için. süreç de bu şekilde
statik kapsam belirleme ile başlar, ancak ikisi arasındaki benzerliğin olduğu yer burasıdır.
teknikler biter. Yerel bildirimlerin aranması başarısız olduğunda, bildirimler
dinamik ebeveynin veya arama fonksiyonunun aranır. için bir beyanname ise
x orada bulunmaz, arama o fonksiyonun dinamik ebeveyninde devam eder,
ve böylece x için bir bildirim bulunana kadar . Herhangi bir dinamikte hiçbiri bulunamazsa
ata, bu bir çalışma zamanı hatasıdır.
Önceki örnekte sub2 için iki farklı çağrı dizisini düşünün .
İlk olarak, büyük aramalar abon1 çağırır Sub2 . Bu durumda, arama şuradan başlar:
Yerel prosedür sub2 , arayanın için sub1 bir bildiri, x olduğu
bulundu. Dolayısıyla, bu durumda sub2'deki x'e yapılan başvuru , sub1'de bildirilen x'e yöneliktir .
Sonra, sub2 doğrudan denir büyük . Bu durumda, sub2'nin dinamik ebeveyni
olan büyük ve referans etmektir x beyan Big .
Statik kapsam kullanılmışsa, tartışılan arama dizilerinden herhangi birinde,
referans x de sub2 olacaktır büyük ‘in x .
Perl'in dinamik kapsam belirlemesi olağandışıdır—aslında, tam olarak bu şekilde değildir.
semantik genellikle geleneksel olan olmasına rağmen, bu bölümde küfür
dinamik kapsam belirleme (bkz. Programlama Alıştırması 1).
5.5.7 Dinamik Kapsamın Değerlendirilmesi
Dinamik kapsam belirlemenin programlama üzerindeki etkisi derindir. Dinamik olduğunda
Kapsam belirleme kullanıldığında, bir program tarafından görülebilen yerel olmayan değişkenlerin doğru nitelikleri
ifade statik olarak belirlenemez. Ayrıca, bir referans
böyle bir değişkenin adı her zaman aynı değişkene ait değildir. Alt yazıdaki bir açıklama
yerel olmayan bir değişkene referans içeren bir program, farklı bir değişkene referans verebilir.
alt programın farklı yürütmeleri sırasında yerel olmayan değişkenler. Birkaç çeşit
programlama problemlerinin çoğu, doğrudan dinamik kapsamdan kaynaklanmaktadır.

sayfa 250
5.6 Kapsam ve Ömür 229
İlk olarak, bir alt programın yürütülmesine başladığı zaman başlayan zaman aralığı boyunca.
ve bu yürütme sona erdiğinde sona eren, alt programın yerel değişkenleri
gram'ın tümü, metinsel yapısından bağımsız olarak, herhangi bir diğer çalışan alt program tarafından görülebilir.
yakınlık veya yürütmenin şu anda yürütülmekte olan alt programa nasıl ulaştığı. Orası
yerel değişkenleri bu erişilebilirlikten korumanın bir yolu yoktur. alt programlar
her zaman önceden adlandırılan tüm alt programların ortamında yürütülür.
infazlarını henüz tamamlamadılar. Sonuç olarak, dinamik kapsam belirleme sonuçları
statik kapsam belirlemeden daha az güvenilir programlarda.
Dinamik kapsam belirleme ile ilgili ikinci bir sorun, kontrol referansının yazılmamasıdır.
yerel olmayanlara statik olarak gelir. Bu sorun, statik olarak yapılamamasından kaynaklanmaktadır.
yerel olmayan olarak başvurulan bir değişkenin bildirimini bulun.
Dinamik kapsam belirleme ayrıca programların okunmasını çok daha zor hale getirir,
çünkü alt programların çağrı sırasının belirlenmesi için bilinmesi gerekir.
yerel olmayan değişkenlere yapılan referansların anlamı. Bu görev neredeyse imkansız olabilir.
bir insan okuyucu için mümkün.
Son olarak, dinamik kapsamlı dillerde yerel olmayan değişkenlere erişim
statik kapsam belirleme kullanıldığında yerel olmayanlara erişimden çok daha uzun. Sebep
Bunun için Bölüm 10'da açıklanmıştır.
Öte yandan, dinamik kapsam belirleme değersiz değildir. birçoğunda
durumlarda, bir alt programdan diğerine aktarılan parametreler değişkendir.
arayanda tanımlanan yetenekler. Bunların hiçbirinin bir
dinamik olarak kapsamlı dil, çünkü çağrılan dillerde örtük olarak görünürler.
alt program.
Dinamik kapsam belirlemenin neden bu kadar yaygın olarak kullanılmadığını anlamak zor değil
statik kapsam olarak. Statik kapsamlı dillerdeki programların okunması daha kolaydır,
dinamik kapsamlı programlarda daha güvenilirdir ve eşdeğer programlardan daha hızlı yürütülür.
Diller. Dinamik kapsam belirleme tam da bu nedenlerle değiştirildi.
LISP'in en güncel lehçelerinde statik kapsam belirleme ile. için uygulama yöntemleri
hem statik hem de dinamik kapsam belirleme Bölüm 10'da tartışılmaktadır.
5.6 Kapsam ve Ömür
Bazen bir değişkenin kapsamı ve ömrü birbiriyle ilişkili görünebilir. İçin
örneğin, aşağıdakileri içeren bir Java yönteminde bildirilen bir değişkeni düşünün:
yöntem çağrısı yok. Böyle bir değişkenin kapsamı, bildiriminden
yöntemin sonu. Bu değişkenin ömrü, başlangıç ​​zaman periyodudur.
metoda girildiğinde başlar ve metod çalıştırıldığında biter
sona erer. Değişkenin kapsamı ve ömrü açıkça olmasa da
aynı, çünkü statik kapsam metinsel veya uzamsal bir kavramken yaşam süresi bir
zamansal kavram, en azından bu durumda ilişkili görünüyorlar.
Kapsam ve yaşam süresi arasındaki bu belirgin ilişki geçerli değildir.
diğer durumlar. Örneğin, C ve C++'da, bir
static belirteci kullanan işlev , bunun kapsamına statik olarak bağlıdır.
işlev ve ayrıca depolamaya statik olarak bağlıdır. Yani kapsamı statik ve yereldir.
işleve, ancak ömrü programın tüm yürütülmesine kadar uzanır.
bunun bir parçası.

Sayfa 251
230
Bölüm 5 İsimler, Bağlar ve Kapsamlar
Alt program çağrıları söz konusu olduğunda kapsam ve yaşam süresi de ilgisizdir.
Aşağıdaki C++ işlevlerini göz önünde bulundurun:
void baskı başlığı() {
. . .
} /* yazıcı başlığının sonu */
geçersiz hesaplama() {
int toplamı;
. . .
baskı başlığı();
} /* hesaplamanın sonu */
Değişken toplamının kapsamı tamamen hesaplama içinde bulunur
işlev. Baskı başlığı işlevinin gövdesine kadar uzanmaz , ancak
printheader , hesaplamanın yürütülmesinin ortasında yürütülür . Ancak,
toplamın ömrü, yazıcı başlığının yürütüldüğü süre boyunca uzar .
Yazıcı başlığına yapılan çağrıdan önce depolama konumu toplamı ne olursa olsun ,
bu bağlama, yazdırma başlığının yürütülmesi sırasında ve sonrasında devam edecek .
5.7 Referans Ortamları
Referans çevresi açıklamada tüm değişkenlerin koleksiyon
açıklamada görünenler. Bir ifadenin referans ortamı
statik kapsamlı bir dil, yerel kapsamında bildirilen değişkenler artı col-
ata kapsamlarının görünür olan tüm değişkenlerinin seçimi. Böyle bir dilde,
bir ifadenin referans ortamına, bu ifade kullanılırken ihtiyaç duyulur.
kod ve veri yapıları referansları izin oluşturulabilir, böylece derlenmiş olan
çalışma süresi boyunca diğer kapsamlardaki değişkenlere. Uygulama teknikleri
hem statik hem de dinamik kapsamlı dillerde yerel olmayan değişkenlere referanslar
Bölüm 10'da tartışılmaktadır.
Python'da, fonksiyon tanımları ile kapsamlar oluşturulabilir. referans
bir ifadenin ortamı, yerel değişkenleri ve tüm değişkenleri içerir
ifadenin iç içe olduğu fonksiyonlarda bildirildi (değişkenler hariç)
daha yakın işlevlerdeki bildirimlerle gizlenen yerel olmayan kapsamlarda). Her biri
fonksiyon tanımı yeni bir kapsam ve dolayısıyla yeni bir ortam yaratır. Düşünmek
aşağıdaki Python iskelet programı:
g = 3; # Küresel
tanım alt1():
a = 5; # Yerel oluşturur
b = 7; # Başka bir yerel oluşturur
. . .
1
def alt2 ():
küresel g; # Global g artık burada atanabilir

Sayfa 252
5.7 Referans Ortamları 231
c = 9; # Yeni bir yerel oluşturur
. . .
2
def sub3 ():
yerel olmayan c: # Yerel olmayan c'yi burada görünür yapar
g = 11; # Yeni bir yerel oluşturur
. . .
3
Belirtilen program noktalarının referans ortamları aşağıdaki gibidir:
Nokta
Referans Ortamı
1
yerel a ve b (alt1'in), referans için global g,
ama atama için değil
2
yerel c (sub2'nin), hem referans hem de global g için
ödev için
3
yerel olmayan c (sub2'nin), yerel g (sub3'ün)
Şimdi bu iskelet programının değişken bildirimlerini düşünün. Öncelikle,
sub1'in kapsamı daha yüksek bir seviyede olmasına rağmen (daha az derindir) unutmayın.
İç içe) daha sub3 , kapsamı sub1 statik bir atası değildir sub3 yüzden,
sub3 , sub1 içinde bildirilen değişkenlere erişime sahip değildir . iyi var
bunun nedeni. sub1'de bildirilen değişkenler yığın dinamiktir, bu nedenle
sub1 yürütülmüyorsa depolamaya bağlı değildir. çünkü sub3 olabilir
yürütmede sub1 olmadığında, içindeki değişkenlere erişmesine izin verilemez.
yürütme sırasında mutlaka depolamaya bağlı olmayacak olan sub1
gelebilsin sub3 .
Yürütülmesi başlamış ancak henüz sonlandırılmamışsa , bir alt program etkindir.
uluslu. Dinamik olarak kapsamlı bir ifadenin referans ortamı
dil, yerel olarak bildirilen değişkenler ve diğer tüm alt programların değişkenleridir.
Şu anda aktif olan gramlar. Bir kez daha, aktif alt programdaki bazı değişkenler
gram referans ortamından gizlenebilir. Son alt program
aktivasyonlar, aynı değişkenleri gizleyen değişkenler için bildirimlere sahip olabilir.
önceki alt program aktivasyonlarındaki isimler.
Aşağıdaki örnek programı inceleyiniz. Tek işlevin olduğunu varsayalım
: çağrılar şu vardır ana aramalar sub2 , aramaları sub1 .
geçersiz sub1() {
int a, b;
. . .
1
} /* sub1'in sonu */
geçersiz sub2() {
int b, c;
.. . .
2
alt1();
} /* sub2'nin sonu */
geçersiz ana() {

Sayfa 253
232
Bölüm 5 İsimler, Bağlar ve Kapsamlar
int c, d;
. . .
3
alt2();
} /* ana bölümün sonu */
Belirtilen program noktalarının referans ortamları şu şekildedir:
şöyle:
5.8 Adlandırılmış Sabit s
Bir isimli sabit sadece bir kez bir değere bağlı bir değişkendir. Adlandırılmış
sabitler, okunabilirliğe ve program güvenilirliğine yardımcı olarak yararlıdır. okunabilirlik
örneğin, sabit yerine pi adı kullanılarak geliştirilebilir.
3.14159265 .
Adlandırılmış sabitlerin bir başka önemli kullanımı, bir programı parametreleştirmektir.
Örneğin, sabit sayıda veri değerini işleyen bir program düşünün,
100 diyelim. Böyle bir program genellikle 100 sabitini birkaç yerde kullanır.
dizi alt simge aralıklarını bildirmek ve döngü kontrol limitleri için. Yi hesaba kat
aşağıdaki iskelet Java programı segmenti:
geçersiz örnek() {
int [] intList = yeni int [100];
String[] strList = yeni String[100];
. . .
for (indeks = 0; dizin < 100; dizin++) {
. . .
}
. . .
for (indeks = 0; dizin < 100; dizin++) {
. . .
}
. . .
ortalama = toplam / 100;
. . .
}
Bu programın farklı sayıdaki programlarla başa çıkmak için değiştirilmesi gerektiğinde
veri değerleri, 100'ün tüm oluşumları bulunmalı ve değiştirilmelidir. büyük
Nokta
Referans Ortamı
1
Bir ve b arasında sub1 , C arasında sub2 , d ait ana , ( c ait ana
ve b arasında sub2 gizlidir)
2
b ve c ve sub2 , d ait ana , ( C arasında ana gizlenir)
3
c ve d ve ana

Sayfa 254
5.8 Adlandırılmış Sabitler
233
program, bu sıkıcı ve hataya açık olabilir. Daha kolay ve daha güvenilir
yöntem, aşağıdaki gibi bir program parametresi olarak adlandırılmış bir sabit kullanmaktır:
geçersiz örnek() {
son int uzunluk = 100;
int [] intList = yeni int [len];
String[] strList = new String[len];
. . .
for (indeks = 0; dizin < len; dizin++) {
. . .
}
. . .
for (indeks = 0; dizin < len; dizin++) {
. . .
}
. . .
ortalama = toplam / len;
. . .
}
Şimdi, uzunluk değiştirileceği zaman, sadece bir satır değiştirilmelidir.
( len değişkeni ), pro-
gram. Bu, soyutlamanın faydalarının başka bir örneğidir. adı len
bazı dizilerdeki eleman sayısı ve sayı için bir soyutlamadır.
bazı döngülerdeki yinelemelerin sayısı. Bu, adlandırılmış sabitlerin nasıl yardımcı olabileceğini gösterir.
değiştirilebilirlik.
Ada ve C++, değerlerin adlandırılmış sabitlere dinamik olarak bağlanmasına izin verir. Bu
değişkenleri içeren ifadelerin dec'deki sabitlere atanmasına izin verir.
larasyonlar. Örneğin, C++ deyimi
const int sonuç = 2 * genişlik + 1;
sonucu , değeri şuna ayarlanmış sabit adlı bir tamsayı türü olarak bildirir .
2 * genişlik + 1 ifadesinin değeri , burada genişlik değişkeninin değeri
sonuç tahsis edildiğinde ve değerine bağlı olduğunda görünür olmalıdır .
Java ayrıca değerlerin adlandırılmış sabitlere dinamik olarak bağlanmasına da izin verir. Java'da,
adlandırılmış sabitler, son ayrılmış sözcükle tanımlanır (daha önce olduğu gibi
örnek). Başlangıç ​​değeri, beyan beyanında veya bir
sonraki atama beyanı. Atanan değer ile belirtilebilir
herhangi bir ifade.
C#'ın iki tür adlandırılmış sabiti vardır: const ile tanımlananlar ve
salt okunur olarak tanımlanır . Const örtük olan adlandırılmış sabitler,
static , değerlere statik olarak bağlıdır; yani, değerlere bağlıdırlar
derleme zamanı, yani bu değerler yalnızca değişmez değerlerle veya
diğer const üyeleri. Salt okunur dynami- olan adlandırılmış sabitler,
değerlere kesin olarak bağlı, bildirimde veya statik ile atanabilir

Sayfa 255
234
Bölüm 5 İsimler, Bağlar ve Kapsamlar
yapıcı. 12 Dolayısıyla, eğer bir program değeri şu olan sabit değerli bir nesneye ihtiyaç duyarsa
programın her kullanımında aynıdır, bir const sabiti kullanılır. Ancak, eğer bir
program, değeri yalnızca aşağıdaki durumlarda belirlenen sabit değerli bir nesneye ihtiyaç duyar.
nesne oluşturulur ve pro-
gram, daha sonra salt okunur bir sabit kullanılır.
Ada, adlandırılmış numaralandırma sabitlerine ve yapılandırılmış türlere izin verir;
Bölüm 6'da tartışılmaktadır.
Değerleri adlandırılmış sabitlere bağlama tartışması, doğal olarak şu sonuca götürür:
başlatma konusu, çünkü bir değeri adlandırılmış bir sabite bağlamak aynıdır
süreç dışında kalıcıdır.
Birçok durumda, değişkenler için değerden önce değerlere sahip olmak uygundur.
Bildirildikleri program veya alt programın kodu yürütülmeye başlar.
ing. Bir değişkenin depolamaya bağlı olduğu anda bir değere bağlanması,
başlatma denir . Değişken depolamaya statik olarak bağlıysa, bağlama ve
başlatma, çalıştırma zamanından önce gerçekleşir. Bu durumlarda, başlangıç ​​değeri olmalıdır
bir hazır bilgi veya yalnızca değişmez olmayan işlenenleri adlandırılmış bir ifade olarak belirtilir
önceden tanımlanmış sabitler. Depolama bağlaması dinamikse,
başlatma da dinamiktir ve başlangıç ​​değerleri herhangi bir ifade olabilir.
Çoğu dilde, başlatma, oluşturan bildirimde belirtilir.
değişken. Örneğin, C++'da
int toplam = 0;
int * ptrSum = ∑
karakter adı[] = "George Washington Carver";
ÖZET
Büyük/küçük harf duyarlılığı ve adların özel sözcüklerle ilişkisi;
ayrılmış kelimeler veya anahtar kelimeler, isimler için tasarım sorunlarıdır.
Değişkenler, özniteliklerin altılısı ile karakterize edilebilir: isim, adres,
değer, tür, yaşam süresi ve kapsam.
Takma adlar, aynı depolama adresine bağlı iki veya daha fazla değişkendir. Onlar
Güvenilirlik açısından zararlı olarak kabul edilirler ancak tamamen ortadan kaldırılması zordur.
bir dilden.
Bağlama, özniteliklerin program varlıklarıyla ilişkilendirilmesidir. Bilgi
özniteliklerin varlıklara bağlanma zamanlarının anlaşılması,
programlama dillerinin semantiği. Bağlama statik veya dinamik olabilir. Aralık
Açık ya da örtük açıklamalar, statik durumu belirtmenin bir yolunu sağlar.
değişkenlerin türlere bağlanması. Genel olarak, dinamik bağlama daha fazla esnekliğe izin verir.
ancak okunabilirlik, verimlilik ve güvenilirlik pahasına.
12. C#'daki statik kurucular, sınıf somutlaştırılmadan önce belirsiz bir zamanda çalışır.

Sayfa 256
Soruları İncele
235
Skaler değişkenler, skalaları dikkate alınarak dört kategoriye ayrılabilir.
yaşam süreleri: statik, yığın dinamiği, açık yığın dinamiği ve örtük yığın dinamiği.
Statik kapsam belirleme, ALGOL 60'ın ve onun bazı alt yapılarının temel bir özelliğidir.
dans. Görünürlük sağlamak için basit, güvenilir ve verimli bir yöntem sağlar.
alt programlarda yerel olmayan değişkenlerin Dinamik kapsam belirleme, daha fazla esneklik sağlar.
statik kapsam belirlemeden daha kolay olabilir, ancak yine, okunabilirlik, güvenilirlik pahasına,
ve verimlilik.
Çoğu işlevsel dil, kullanıcının let ile yerel kapsamlar oluşturmasına izin verir.
tanımlı adlarının kapsamını sınırlayan yapılar.
Bir ifadenin referans ortamı, tüm
bu ifadeye görünen değişkenler.
Adlandırılmış sabitler, değerlere yalnızca bir kez bağlanan değişkenlerdir.
İNCELEME SORULARI
1. İsimler için tasarım sorunları nelerdir?
2. Büyük/küçük harfe duyarlı adların potansiyel tehlikesi nedir?
3. Ayrılmış kelimeler hangi yönden anahtar kelimelerden daha iyidir?
4. Takma ad nedir?
5. C++ başvuru değişkenlerinin hangi kategorisi her zaman takma addır?
6. Bir değişkenin l değeri nedir ? Nedir r- değeri?
7. Bağlama ve bağlama süresini tanımlayın .
8. Dil tasarımı ve uygulamasından sonra [dört kez bağlama nedir?
bir programda yer alabilir mi?]
9. Statik bağlamayı ve dinamik bağlamayı tanımlayın .
10. Örtülü beyanların avantajları ve dezavantajları nelerdir?
11. Dinamik tip bağlamanın avantajları ve dezavantajları nelerdir?
12. Statik , yığın dinamik , açık yığın dinamik ve kapalı yığın tanımlayın.
dinamik değişkenler . Avantajları ve dezavantajları nelerdir?
13. Ömür boyu , kapsam , statik kapsam ve dinamik kapsamı tanımlayın .
14. Statik kapsamlı bir program bağlamında yerel olmayan bir değişkene nasıl başvurulur?
tanımına bağlı mı?
15. Statik kapsam belirlemeyle ilgili genel sorun nedir?
16. Bir ifadenin referans ortamı nedir?
17. Bir alt programın statik atası nedir? dinamik ata nedir
bir alt program?
18. Blok nedir?
19. İşlevsel dillerde let yapılarının amacı nedir ?
20. Bir ML let con'da tanımlanan adlar arasındaki fark nedir?
C bloğunda bildirilen değişkenlerden struct?

Sayfa 257
236
Bölüm 5 İsimler, Bağlar ve Kapsamlar
21. Bir F # kapsülleme Açıklayın izin bir fonksiyonu içinde ve dışında bütün
fonksiyonlar.
22. Dinamik kapsam belirlemenin avantajları ve dezavantajları nelerdir?
23. Adlandırılmış sabitlerin avantajları nelerdir?
PROBLEM SETİ
1. Aşağıdaki tanımlayıcı formlardan hangisi en çok okunabilir? destekleyin
karar.
Satış Toplamı
satışların toplamı
SUMOFSATLAR
2. Bazı programlama dilleri türsüzdür. bariz avantajlar nelerdir?
Bir dilde tip olmamasının dezavantajları ve dezavantajları?
3. Bir aritmetik işleç içeren basit bir atama ifadesi yazın.
bildiğin dil. İfadenin her bir bileşeni için çeşitli
deyim olduğunda semantiği belirlemek için gerekli olan bağlamalar
uygulanmış. Her bağlama için, dil için kullanılan bağlama süresini belirtin.
4. Dinamik tip bağlama, örtük yığın dinamik değişkeni ile yakından ilişkilidir.
yetenekli. Bu ilişkiyi açıklayın.
5. Bir alt programdaki geçmişe duyarlı bir değişken olduğunda bir durumu tanımlayın.
kullanışlı.
6. Aşağıdaki JavaScript iskelet programını düşünün:
// Ana program
var x;
işlev alt1() {
var x;
işlev alt2() {
. . .
}
}
işlev alt3() {
. . .
}
Bu programın yürütülmesinin aşağıdaki birim sırayla olduğunu varsayalım:
ana çağrılar alt1
abon1 çağrılar sub2
sub2 , sub3'ü çağırır

Sayfa 258
Problem Seti
237
a. Aşağıda statik kapsam belirlemeyi varsayarsak,
x'in genişliği, x'e bir referans için doğru olanı mı?
Bence. alt1
ii. alt2
iii. alt3
B. A bölümünü tekrarlayın, ancak dinamik kapsam belirlemeyi kabul edin.
7. Aşağıdaki JavaScript programının kullanılarak yorumlandığını varsayalım.
statik kapsam kuralları. sub1 işlevinde hangi x değeri görüntülenir ?
Dinamik kapsam kuralları altında , işlevde hangi x değeri görüntülenir?
alt1 ?
var x;
işlev alt1() {
document.write("x = " + x + "<br />");
}
işlev alt2() {
var x;
x = 10;
alt1();
}
x = 5;
alt2();
8. Aşağıdaki JavaScript programını düşünün:
var x, y, z;
işlev alt1() {
var a, y, z;
işlev alt2() {
var a, b, z;
. . .
}
. . .
}
işlev alt3() {
var a, x, w;
. . .
}

Sayfa 259
238
Bölüm 5 İsimler, Bağlar ve Kapsamlar
Tüm değişkenleri, bulundukları program birimleriyle birlikte listeleyin.
sub1 , sub2 ve sub3 gövdelerinde görünen beyanlar , varsayalım.
statik kapsam belirleme kullanılır.
9. Aşağıdaki Python programını düşünün:
x = 1;
y = 3;
z = 5;
tanım alt1():
a = 7;
y = 9;
z = 11;
. . .
tanım alt2():
küresel x;
a = 13;
x = 15;
w = 17;
. . .
def sub3 ():
yerel olmayan a;
a = 19;
b = 21;
z = 23;
. . .
. . .
Tüm değişkenleri, bulundukları program birimleriyle birlikte listeleyin.
sub1 , sub2 ve sub3 gövdelerinde görünen beyanlar , varsayalım.
statik kapsam belirleme kullanılır.
10. Aşağıdaki C programını göz önünde bulundurun:
void fun( void ) {
int a, b, c; /* tanım 1 */
. . .
süre (. . .) {
int b, c, d; /*tanım 2 */
. . .
1
süre (. . .) {

Sayfa 260
Problem Seti
239
int c, d, e; /* tanım 3 */
. . .
2
}
. . .
3
}
. . .
4
}
Bu fonksiyondaki dört işaretli noktanın her biri için, her bir görünür değişkeni listeleyin.
mümkün, onu tanımlayan tanım ifadesinin numarası.
11. Aşağıdaki iskelet C programını düşünün:
void fun1( void ); /* prototip */
void fun2( void ); /* prototip */
void fun3( void ); /* prototip */
geçersiz ana() {
int a, b, c;
. . .
}
void fun1( void ) {
int b, c, d;
. . .
}
void fun2( void ) {
int c, d, e;
. . .
}
void fun3( void ) {
int d, e, f;
. . .
}
Aşağıdaki arama dizileri göz önüne alındığında ve bu dinamik kapsamı varsayarak-
kullanıldığında, son işlevin yürütülmesi sırasında hangi değişkenlerin görünür olduğu
çağrıldı mı? Görünür her değişkene işlevin adını dahil edin.
hangi tanımlandı.
a. ana çağrılar fun1 ; fun1 çağırır FUN2 ; FUN2 çağırır fun3 .
B. ana çağrılar fun1 ; fun1 çağırır fun3.
C. ana çağrılar fun2 ; FUN2 çağırır fun3 ; fun3 çağırır FUN1 .

Sayfa 261
240
Bölüm 5 İsimler, Bağlar ve Kapsamlar
D. ana çağrılar fun3 ; fun3 çağırır FUN1 .
e. ana çağrılar fun1 ; fun1 çağırır fun3 ; fun3 çağırır FUN2 .
F. ana çağrılar fun3 ; fun3 çağırır FUN2 ; FUN2 çağırır FUN1 .
12. JavaScript benzeri sözdizimiyle yazılmış aşağıdaki programı düşünün:
// ana program
var x, y, z;
işlev alt1() {
var a, y, z;
. . .
}
işlev alt2() {
var a, b, z;
. . .
}
işlev alt3() {
var a, x, w;
. . .
}
Aşağıdaki arama dizileri göz önüne alındığında ve bu dinamik kapsamı varsayarak-
kullanıldığında, son alt programın yürütülmesi sırasında hangi değişkenlerin görünür olduğu
gram aktif mi? Her görünür değişkene birimin adını ekleyin
nerede ilan edilir.
a. ana çağrılar sub1 ; abon1 çağırır Sub2 ; sub2 , sub3'ü çağırır .
B. ana çağrılar sub1 ; sub1 sub3'ü çağırır .
C. ana çağrılar sub2 ; sub2 , sub3'ü çağırır ; sub3 çağrılar abon1 .
D. ana çağrılar sub3 ; sub3 çağrılar abon1 .
e. ana çağrılar sub1 ; sub1 sub3'ü çağırır ; sub3 çağrılar sub2 .
F. ana çağrılar sub3 ; sub3 çağırır Sub2 ; sub2 çağrılar abon1 .
PROGRAMLAMAALIŞTIRMALAR
1. Perl, hem statik hem de bir tür dinamik kapsam belirlemeye izin verir. Bir Perl pro-
her ikisini de kullanan ve ikisinin etkisindeki farkı açıkça gösteren gram.
bölümünde açıklanan dinamik kapsam arasındaki farkı net bir şekilde açıklayın.
bu bölüm ve Perl'de uygulanan bölüm.

Sayfa 262
Programlama Alıştırmaları
241
2. Farkı açıkça gösteren bir Ortak LISP programı yazın
statik ve dinamik kapsam arasında.
3. Üç derin ve iç içe geçmiş alt programlara sahip bir JavaScript komut dosyası yazın.
iç içe geçmiş her bir alt program, tüm programlarında tanımlanan değişkenlere başvurur.
alt programları içerir.
4. Programlama Egzersizi 3'ü Python ile tekrarlayın.
5. Aşağıdaki ifade dizisini içeren bir C işlevi yazın:
x = 21;
int x;
x = 42;
Programı çalıştırın ve sonuçları açıklayın. Aynı kodu C++ ile yeniden yazın
ve Java ve sonuçları karşılaştırın.
6. Kapsamını belirlemek için C++, Java ve C# dillerinde test programları yazın.
for deyiminde bildirilen bir değişken . Özellikle, kodun
Böyle değişken bir gövdesi sonra görünür olup olmadığını belirlemek için
Beyan.
7. C veya C++ dilinde üç fonksiyon yazın: büyük bir dizi durumu bildiren bir fonksiyon.
cally, yığında aynı büyük diziyi bildiren ve
yığından aynı büyük diziyi oluşturur. Alt programların her birini çağırın
çok sayıda (en az 100.000) ve gereken süreyi çıktı
her biri tarafından. Sonuçları açıklayın.

Sayfa 263
Bu sayfa bilerek boş bırakılmıştır

Sayfa 264
243
6.1 Giriş
6.2 İlkel Veri Tipleri
6.3 Karakter Dizisi Türleri
6.4 Kullanıcı Tanımlı Sıra Türleri
6.5 Dizi Türleri
6.6 İlişkili Diziler
6.7 Kayıt Türleri
6.8 Grup Türleri
6.9 Liste Türleri
6.10 Birlik Türleri
6.11 İşaretçi ve Referans Türleri
6.12 Tip Kontrolü
6.13 Güçlü Yazma
6.14 Tip Eşdeğerliği
6.15 Teori ve Veri Tipleri
6
Veri tipleri

Sayfa 265
244
Bölüm 6 Veri Tipleri
Bu bölümde ilk olarak veri tipi kavramı ve özellikleri tanıtılmaktadır.
ortak ilkel veri türleri. Ardından, numaralandırma tasarımları ve
alt aralık türleri tartışılır. Ardından, yapılandırılmış veri türlerinin ayrıntıları—
özellikle diziler, ilişkisel diziler, kayıtlar, demetler, listeler ve birlikler - araştırmadır.
kapılı. Bu bölümü, işaretçilere ve referanslara derinlemesine bir bakış izler.
Çeşitli veri türleri kategorilerinin her biri için tasarım konuları belirtilmiştir.
ve bazı ortak dillerin tasarımcıları tarafından yapılan tasarım seçimleri
tarif edilmiştir. Daha sonra bu tasarımlar değerlendirilir.
Sonraki üç bölüm, tip kontrolünün kapsamlı bir incelemesini sağlar,
güçlü yazma ve eşdeğerlik kurallarını yazın. Bölümün son kısmı kısaca
Veri türleri teorisinin temellerini tanıtır.
Veri türleri için uygulama yöntemleri bazen veri türleri üzerinde önemli bir etkiye sahiptir.
onların tasarımı. Bu nedenle, çeşitli veri türlerinin uygulanması bir başka önemli
Bu bölümün tant kısmı, özellikle diziler.
6.1 Giriş
Bir veri türü , bir veri değerleri koleksiyonunu ve bir dizi önceden tanımlanmış işlemi tanımlar.
bu değerler üzerinde. Bilgisayar programları, verileri manipüle ederek sonuçlar üretir.
Bunu ne kadar kolay gerçekleştirebileceklerini belirlemede önemli bir faktör
Görev, kullanılan dilde mevcut olan veri türlerinin, kullanılan dille ne kadar iyi eşleştiğidir.
ele alınan problemin gerçek dünyadaki nesneleri. Bu nedenle, çok önemli
bir dilin uygun bir veri türleri ve yapıları koleksiyonunu desteklediğini.
Veri yazmanın çağdaş kavramları son zamanlarda gelişmiştir.
55 yıl. En eski dillerde, tüm problem alanı veri yapılarının olması gerekiyordu.
yalnızca birkaç temel dil destekli veri yapısıyla modellenmiştir. Örneğin,
90 öncesi Fortrans'ta, dizilerle bağlantılı listeler ve ikili ağaçlar uygulanıyordu.
COBOL'un veri yapıları Fortran I'den ilk adımı attı
programcıların ondalık veri değerlerinin doğruluğunu belirlemesine izin vererek model,
ve ayrıca bilgi kayıtları için yapılandırılmış bir veri türü sağlayarak. PL/I
tamsayı ve kayan nokta için doğruluk belirtiminin kapasitesini genişletti
türleri. Bu, o zamandan beri Ada ve Fortran'a dahil edilmiştir. tasarımcıları
PL/I, çok çeşitli veri türlerini desteklemek amacıyla birçok veri türü içeriyordu.
uygulamalar. ALGOL 68'de tanıtılan daha iyi bir yaklaşım, birkaç
temel tipler ve bir programa izin veren birkaç esnek yapı-tanımlama operatörü
mer her ihtiyaç için bir veri yapısı tasarlamak. Açıkçası, bu en çok biriydi
veri tipi tasarımının evriminde önemli gelişmeler. Kullanıcı tanımlı türler
için anlamlı adların kullanılması yoluyla daha iyi okunabilirlik sağlar.
türleri. Özel bir kullanım kategorisinin değişkenlerinin tip kontrolüne izin verirler,
ki aksi takdirde mümkün olmazdı. Kullanıcı tanımlı türler ayrıca modifiye edilebilir-
ity: Bir programcı, bir programdaki bir değişken kategorisinin türünü değiştirebilir
yalnızca bir tür tanımı deyimini değiştirerek.
Kullanıcı tanımlı tip kavramını bir adım daha ileri götürerek şu sonuca varıyoruz:
çoğu programlama dili tarafından desteklenen soyut veri türleri
1980'lerin ortalarından beri tasarlanmıştır. Soyut bir veri türünün temel fikri

Sayfa 266
6.1 Giriş 245
kullanıcı tarafından görülebilen bir türdeki arayüzün, arayüzden ayrılmasıdır.
gizli olan bu tür değerler üzerinde gösterim ve işlemler kümesi
kullanıcıdan. Üst düzey bir programlama dili tarafından sağlanan tüm türler
soyut veri türleridir. Kullanıcı tanımlı soyut veri türleri ayrıntılı olarak tartışılır
Bölüm 11'de.
Bir programlama dilinin tip sisteminin bir takım kullanımları vardır.
Bunlardan en pratik olanı hata tespitidir. Türün süreci ve değeri
dilin tip sistemi tarafından yönlendirilen kontroller tartışılmaktadır.
Bölüm 6.12'de. Tip sisteminin ikinci bir kullanımı, sağladığı yardımdır.
program modülerizasyonu. Bu, modüller arası tip kontrolünden kaynaklanır
modüller arasındaki arayüzlerin tutarlılığını sağlar. Başka bir kullanımı
bir tip sistem dokümantasyondur. Bir program belgesindeki tür bildirimleri
programın davranışı hakkında ipuçları sağlayan verileri hakkında bilgi.
Bir programlama dilinin tip sistemi, bir tipin nasıl ilişkilendirildiğini tanımlar.
dildeki her bir ifadeyle ilişkilendirilir ve tür eşdeğeri için kurallarını içerir.
lens ve tip uyumluluğu. Kesinlikle en önemli kısımlarından biri
bir programlama dilinin anlamını anlamak, onun anlamını anlamaktır.
tip sistem.
Emperyal sistemdeki en yaygın iki yapılandırılmış (skaler olmayan) veri türü.
ilişkisel dillerin popülaritesi olmasına rağmen, diller diziler ve kayıtlardır.
diziler son yıllarda önemli ölçüde artmıştır. Listeler merkezi bir parça oldu
Bu tür ilk dilin ortaya çıkmasından bu yana işlevsel programlama dillerinin
1959'da (LISP). Son on yılda, fonksiyonel ürünlerin artan popülaritesi
programlama, öncelikli olarak zorunlu dillere listelerin eklenmesine yol açtı,
Python ve C# gibi.
Yapılandırılmış veri türleri, tür operatörleri veya yapıcılar ile tanımlanır,
tür ifadeleri oluşturmak için kullanılır. Örneğin, C parantez kullanır ve
dizileri ve işaretçileri belirtmek için tür operatörleri olarak yıldız işaretleri.
Değişkenleri terimlerle düşünmek hem mantıksal hem de somut olarak uygundur.
tanımlayıcılardan oluşur. Bir açıklayıcı değişkenin niteliklerin toplamıdır. İçinde
bir uygulama, bir tanımlayıcı, nitelikleri depolayan bir bellek alanıdır.
bir değişkenin. Niteliklerin tümü statik ise, tanımlayıcılar yalnızca
Derleme zamanı. Bu tanımlayıcılar, genellikle bir parçası olarak derleyici tarafından oluşturulur.
sembol tablosu ve derleme sırasında kullanılır. Dinamik nitelikler için,
ancak, tanımlayıcının bir kısmı veya tamamı yürütme sırasında korunmalıdır. İçinde
bu durumda, tanımlayıcı çalışma zamanı sistemi tarafından kullanılır. Her durumda, açıkla-
tors, tip kontrolü ve tahsis için kodun oluşturulması için kullanılır ve
delokasyon işlemleri.
Değişken terimini kullanırken dikkatli olunmalıdır . Sadece kullanan
geleneksel zorunlu diller, tanımlayıcıları değişkenler olarak düşünebilir, ancak bu
veri türleri düşünüldüğünde kafa karışıklığına neden olabilir. Tanımlayıcılarda veri yok
Bazı programlama dillerinde türler. tanımlayıcıları hatırlamak akıllıca olacaktır.
bir değişkenin özelliklerinden sadece biridir.
Nesne kelimesi genellikle bir değişkenin değeri ve boşluk ile ilişkilendirilir.
işgal eder. Ancak bu kitapta, nesneyi yalnızca örnekler için saklı tutuyoruz.
değişkenlerinin değerlerinden ziyade, kullanıcı tanımlı soyut veri türlerinin

Sayfa 267
246
Bölüm 6 Veri Tipleri
önceden tanımlanmış türler Nesne yönelimli dillerde, her sınıfın her örneği,
ister önceden tanımlanmış ister kullanıcı tanımlı olsun, nesne olarak adlandırılır. Nesneler tartışılır
Bölüm 11 ve 12'de ayrıntılı olarak.
Aşağıdaki bölümlerde, birçok yaygın veri türü tartışılmaktadır. Çoğu için,
tipe özel tasarım konuları belirtilmiştir. Hepsi için, bir veya daha fazla örnek
tasarımlar anlatılmaktadır. Bir tasarım sorunu, tüm veri türleri için temeldir: Ne
türdeki değişkenler için işlemler sağlanır ve bunlar nasıl belirtilir?
6.2 İlkel Veri Tipleri
Diğer türler cinsinden tanımlanmayan veri türlerine ilkel denir.
veri türleri . Neredeyse tüm programlama dilleri bir dizi ilkel veri sağlar.
türleri. İlkel türlerden bazıları yalnızca donanımın yansımalarıdır.
örneğin, çoğu tamsayı türü. Diğerleri yalnızca biraz donanım dışı destek gerektirir
onların uygulanması için.
Yapılandırılmış türleri sağlamak için, bir dilin ilkel veri türleri şunlardır:
bir veya daha fazla tür oluşturucu ile birlikte kullanılır.
6.2.1 Sayısal Türler
Birçok erken programlama dilinde yalnızca sayısal ilkel türler vardı. sayısal
türler, bağlamlar tarafından desteklenen tür koleksiyonları arasında hala merkezi bir rol oynamaktadır.
geçici diller
6.2.1.1 Tamsayı
En yaygın ilkel sayısal veri türü tamsayıdır . Birçok bilgisayar-
ers artık birkaç tamsayı boyutunu destekliyor. Bu tamsayı boyutları ve genellikle
diğerleri, bazı programlama dilleri tarafından desteklenir. Örneğin,
Java dört işaretli tamsayı boyutu içerir: byte , short , int ve long . Bazı
C++ ve C# gibi diller, işaretsiz tamsayı türlerini içerir.
sadece işaretsiz tamsayı değerleri için türler. İşaretsiz türler sıklıkla kullanılır
ikili veriler için.
İşaretli bir tamsayı değeri, bir bilgisayarda bir bit dizisi ile temsil edilir;
işareti temsil eden bitlerden biri (tipik olarak en soldaki). Çoğu tamsayı türü
doğrudan donanım tarafından desteklenir. Bir tamsayı türü örneği
doğrudan donanım tarafından desteklenmez, Python'un uzun tamsayı türüdür
(F# ayrıca bu tür tam sayıları sağlar). Bu türdeki değerler sınırsız uzunlukta olabilir.
Uzun tamsayı değerleri, aşağıdaki örnekte olduğu gibi değişmez değerler olarak belirtilebilir:
243725839182756281923L
Python'da sayılamayacak kadar büyük değerler üreten tamsayı aritmetik işlemleri
int tipiyle temsil edilenler, onları uzun tamsayı tipi değerler olarak saklar.

Sayfa 268
6.2 İlkel Veri Tipleri 247
Negatif bir tamsayı, işaret büyüklüğü notasyonunda saklanabilir;
işaret biti negatifi gösterecek şekilde ayarlanmıştır ve bit dizisinin geri kalanı rep-
sayının mutlak değerini gösterir. Bununla birlikte, işaret-büyüklük gösterimi,
kendini bilgisayar aritmetiğine ödünç vermez. Çoğu bilgisayar artık bir gösterim kullanıyor
için uygun olan negatif tamsayıları depolamak için ikiler tamamlayıcısı olarak adlandırılır .
toplama ve çıkarma. İkili tamamlayıcı gösterimde, temsili
pozitifin mantıksal tümleyeni alınarak negatif bir tamsayı oluşturulur.
numaranın sürümü ve bir tane ekleme. Ones-tamamlayıcı notasyonu hala kullanılıyor
bazı bilgisayarlar tarafından. Birler-tamamlayıcı gösterimde, bir tamsayının negatifi
mutlak değerinin mantıksal tümleyeni olarak saklanır. Birler-tamamlayıcı
notasyonun dezavantajı, iki sıfır temsiline sahip olmasıdır. herhangi birini görün
tamsayı gösterimlerinin ayrıntıları için montaj dili programlama kitabı.
6.2.1.2 Kayan Nokta
Kayan - noktalı veri türleri gerçek sayıları modeller, ancak temsiller
birçok gerçek değer için yalnızca yaklaşımlar. Örneğin, hiçbir fon-
zihinsel sayılar veya e (doğal logaritmaların temeli) doğru olabilir
kayan nokta gösterimi ile temsil edilir. Tabii ki, bu sayıların hiçbiri olamaz
herhangi bir sonlu uzayda doğru bir şekilde temsil edilebilir. Çoğu bilgisayarda, yüzer-
nokta sayıları ikili olarak saklanır, bu da sorunu daha da kötüleştirir. Sınav için-
ple, ondalık olarak 0.1 değeri bile sonlu sayıda temsil edilemez.
ikili rakamlar. 1 Kayan nokta türleriyle ilgili diğer bir sorun da doğruluk kaybıdır.
aritmetik işlemler aracılığıyla sorunları hakkında daha fazla bilgi için
kayan nokta gösterimi, sayısal analizle ilgili herhangi bir kitaba bakın.
Kayan nokta değerleri, kesirler ve üsler olarak temsil edilir.
bilimsel gösterimden ödünç alınmıştır. Daha eski bilgisayarlar çeşitli farklı
kayan nokta değerleri için farklı temsiller. Ancak, çoğu yeni makine
IEEE Kayan Nokta Standardı 754 biçimini kullanın. Dil uygulayıcılarının kullandığı
donanım tarafından desteklenen her türlü temsil. Çoğu dil şunları içerir:
genellikle float ve double olarak adlandırılan iki kayan nokta türü . Şamandıra türü,
standart boyut, genellikle dört bayt bellekte saklanır. çift ​​tip
daha büyük kesirli parçaların ve/veya daha geniş bir aralığın olduğu durumlar için sağlanmıştır.
üslere ihtiyaç vardır. Çift duyarlıklı değişkenler genellikle iki kat daha fazla yer kaplar.
kayan değişkenler olarak çok fazla depolama ve bit sayısının en az iki katı sağlar
kesir.
Kayan nokta türüyle temsil edilebilen değerler topluluğu
hassasiyet ve aralık açısından tanımlanır. Kesinlik , fraksiyonun doğruluğudur.
bit sayısı olarak ölçülen bir değerin ulusal kısmı. Aralık bir kombinasyondur
kesirlerin aralığı ve daha da önemlisi, üslerin aralığı.
Şekil 6.1, tekli için IEEE Kayan Nokta Standardı 754 biçimini gösterir.
ve çift kesinlik gösterimi (IEEE, 1985). IEEE biçimlerinin ayrıntıları
Tanenbaum'da (2005) bulunabilir.
1. Ondalık olarak 0.1, 0.00011001110011'dir. . . ikili olarak.

Sayfa 269
248
Bölüm 6 Veri Tipleri
6.2.1.3 Karmaşık
Bazı programlama dilleri karmaşık bir veri türünü destekler; örneğin,
Fortran ve Python. Karmaşık değerler, sıralı çiftler olarak temsil edilir.
kayan nokta değerleri. Python'da, karmaşık bir değişmezin hayali kısmı özeldir.
bir j veya J ile takip edilerek - örneğin,
(7 + 3j)
Karmaşık bir türü destekleyen diller, aritmetik işlemleri içerir.
karmaşık değerler üzerinde
6.2.1.4 Ondalık
İş sistemleri uygulamalarını desteklemek için tasarlanmış daha büyük bilgisayarların çoğu
ondalık veri türleri için donanım desteği vardır. Ondalık veri türleri deposu
ondalık nokta sabit bir konumda olacak şekilde sabit sayıda ondalık basamak
değer. Bunlar, iş verilerinin işlenmesi için birincil veri türleridir ve
bu nedenle COBOL için gereklidir. C# ve F# ayrıca ondalık veri türlerine sahiptir.
Ondalık tipler, ondalık sayıları tam olarak depolayabilme avantajına sahiptir.
imal değerleri, en azından sınırlı bir aralık içinde, yapılamayanlar
kayan nokta ile. Örneğin, 0.1 sayısı (ondalık olarak) tam olarak olabilir
ondalık tipte temsil edilir, ancak gördüğümüz gibi kayan nokta tipinde değil
Bölüm 6.2.1.2. Ondalık türlerin dezavantajları, val-
Üslere izin verilmediğinden ve bunların temsili
Aşağıdaki paragrafta tartışılan nedenlerden dolayı bellek biraz savurgandır.
Ondalık türler, ikili kullanılarak karakter dizilerine çok benzer şekilde depolanır.
ondalık basamaklar için kodlar. Bu temsillere ikili kodlu denir.
ondalık (BCD) . Bazı durumlarda, bayt başına bir basamak saklanır, ancak bazılarında,
bayt başına iki basamak paketlenirler. Her iki durumda da, daha fazla depolama alanı alırlar.
ikili gösterimler. Bir ondalık basamağı kodlamak için en az dört bit gerekir. Orası-
önce, altı basamaklı kodlanmış bir ondalık sayıyı saklamak için 24 bit bellek gerekir.
Şekil 6.1
IEEE kayan nokta
biçimler: (a) tek
kesinlik, (b) çift
hassas
üs
kesir
8 bit
(a)
(B)
İşaret biti
23 bit
11 bit
52 bit
İşaret biti
üs
kesir

Sayfa 270
6.2 İlkel Veri Tipleri 249
Ancak, aynı sayıyı ikili dosyada saklamak sadece 20 bit alır. 2 Opera-
ondalık değerlerle ilgili işlemler, bu kapasiteye sahip makinelerde donanımda yapılır.
yetenekler; aksi takdirde yazılımda simüle edilirler.
6.2.2 Boole Türleri
Boole türleri belki de tüm türlerin en basitidir. Onların değer aralığı
yalnızca iki öğesi vardır: biri doğru, diğeri yanlış için. tanıtıldılar
ALGOL 60'ta ve çoğu genel amaçlı dilde dahil edilmiştir
1960'dan beri tasarlanmıştır. Popüler bir istisna, sayısal ifadenin kullanıldığı C89'dur.
sionlar koşul olarak kullanılır. Bu tür ifadelerde, sıfır olmayan tüm işlenenler
değerler doğru, sıfır ise yanlış olarak kabul edilir. C99 ve C++ olmasına rağmen
Boole tipine sahipler, aynı zamanda sayısal ifadelerin
Boole idi. Sonraki dillerde, Java ve C#'da durum böyle değildir.
Boole türleri genellikle programlardaki anahtarları veya bayrakları temsil etmek için kullanılır.
Tamsayılar gibi diğer türler bu amaçlar için kullanılabilse de, kullanım
Boolean türlerinin daha okunabilir.
Bir Boole değeri tek bir bit ile temsil edilebilir, ancak tek bir
bir miktar belleğe birçok makinede verimli bir şekilde erişilemez, genellikle
tipik olarak bir bayt olan en küçük verimli adreslenebilir bellek hücresinde depolanır.
6.2.3 Karakter Türleri
Karakter verileri bilgisayarlarda sayısal kodlamalar olarak saklanır. Geleneksel olarak,
En yaygın olarak kullanılan kodlama, 8 bitlik kod ASCII'dir (Amerikan Standardı
0 ila 127 arasındaki değerleri kod 128'e kullanan Bilgi Değişimi Kodu)
farklı karakterler. ISO 8859-1 başka bir 8 bitlik karakter kodudur, ancak
256 farklı karakter. Ada 95+, ISO 8859-1'i kullanır.
İş dünyasının küreselleşmesi ve bilgisayarlara duyulan ihtiyaç nedeniyle
ASCII karakter seti, dünyadaki diğer bilgisayarlarla iletişim kurar
yetersiz hale geldi. Buna karşılık, 1991'de Unicode Konsorsiyumu yayınlandı.
UCS-2 standardı, 16 bitlik bir karakter seti. Bu karakter kodu genellikle denir
Unicode. Unicode, dünyanın doğal özelliklerinin çoğundan karakterleri içerir.
Diller. Örneğin, Unicode, kullanılan Kiril alfabesini içerir.
Sırbistan ve Tay rakamları. Unicode'un ilk 128 karakteri aynıdır
ASCII olanlar için. Java, Unicode'u kullanan ilk yaygın olarak kullanılan dildi.
karakter seti. O zamandan beri JavaScript, Python, Perl,
C# ve F#.
1991'den sonra Unicode Konsorsiyumu, Uluslararası
Ulusal Standartlar Organizasyonu (ISO), 4 baytlık bir karakter kodu geliştirdi.
ISO/IEC 10646 Standardında açıklanan UCS-4 veya UTF-32, yayın-
2000 yılında kutladı.
2. Elbette, bir programın çok sayıda büyük ondalık değeri koruması gerekmedikçe,
fark önemsizdir.

Sayfa 271
250
Bölüm 6 Veri Tipleri
Tek karakterlerin kodlarını işleme araçlarını sağlamak için, çoğu
programlama dilleri onlar için ilkel bir tür içerir. Bununla birlikte, Python
tek karakterleri yalnızca uzunluk 1 karakter dizileri olarak destekler.
6.3 Karakter Dizisi Türleri
Bir karakter dizisi türü , değerlerin aşağıdaki dizilerden oluştuğu bir türdür .
karakterler. Karakter dizisi sabitleri çıktıyı etiketlemek için kullanılır ve girdi
ve her türlü verinin çıktısı genellikle diziler cinsinden yapılır. Tabii ki,
karakter dizileri de karakter dizileri yapan tüm programlar için önemli bir türdür.
manipülasyon.
6.3.1 Tasarım Konuları
Karakter dizisi türlerine özgü en önemli iki tasarım sorunu
şunlar:
• Dizeler yalnızca özel bir tür karakter dizisi mi yoksa ilkel bir tür mü olmalı?
• Dizelerin uzunluğu statik mi yoksa dinamik mi olmalı?
6.3.2 Diziler ve İşlemleri
En yaygın dize işlemleri atama, dizileme, alt dizedir.
referans, karşılaştırma ve model eşleştirme.
Bir alt dize başvurusu , belirli bir dizenin bir alt dizesine başvurudur. Alt-
dize referansları, dizilerin daha genel bağlamında tartışılır, burada
alt dize referanslarına dilimler denir .
Genel olarak karakter üzerinde hem atama hem de karşılaştırma işlemleri
dizeler, farklı uzunluklarda dize işlenenleri olasılığı nedeniyle karmaşıktır.
Örneğin, daha kısa bir dizeye daha uzun bir dize atandığında ne olur,
ya da tam tersi? Genellikle bu durumlar için basit ve mantıklı seçimler yapılır,
programcılar genellikle onları hatırlamakta zorlansalar da.
Model eşleştirme, diğer bir temel karakter dizisi işlemidir. bazılarında
dillerde, kalıp eşleştirme doğrudan dilde desteklenir. Diğerlerinde ise
bir işlev veya sınıf kitaplığı tarafından sağlanır.
Dizeler ilkel bir tür olarak tanımlanmadıysa, dize verileri genellikle
tek karakter dizileri ve dilde bu şekilde başvurulur. bu
C ve C++ tarafından alınan yaklaşım.
C ve C++, karakter dizilerini depolamak için karakter dizilerini kullanır. Bu diller pro-
standart kitaplıklar aracılığıyla bir dizi dizi işlemi yapın. birçok kullanım
karakter dizileri ve kitaplık işlevlerinin çoğu, karakter dizileri kuralını kullanır.
sıfırla temsil edilen boş bir özel karakterle sonlandırılır. Bu
dize değişkenlerinin uzunluğunu korumaya bir alternatiftir. kütüphane opera-
tionlar sadece boş karakter görünene kadar işlemlerini yürütürler.
dize çalıştırılıyor. Dizeler üreten kitaplık işlevleri genellikle

Sayfa 272
6.3 Karakter Dizisi Türleri 251
boş karakter. Derleyici tarafından oluşturulan karakter dizisi değişmezleri
ayrıca boş karaktere sahiptir. Örneğin, aşağıdaki beyanı göz önünde bulundurun:
char str[] = "elmalar";
Bu örnekte str , özellikle apples0 olmak üzere bir char öğeleri dizisidir ;
0 boş karakterdir.
Karakter dizileri için en sık kullanılan kitaplık işlevlerinden bazıları
C ve C++'da dizeleri hareket ettiren strcpy vardır; katener olan strcat
verilen bir dize diğerine; sözlükbilimsel olarak karşılaştıran strcmp
(karakter kodlarının sırasına göre) verilen iki dizi; ve strlen , hangi
verilen dizedeki boş değeri saymadan karakter sayısını döndürür.
Dize işleme işlevinin çoğu için parametreler ve dönüş değerleri
ları vardır Char noktada bunun diziler için işaretçiler Char . Parametreler de olabilir
dize değişmezleri.
Aynı zamanda C standart kitaplığının dize işleme işlevleri
C++'da mevcuttur, doğası gereği güvensizdir ve çok sayıda programlamaya yol açmıştır.
hatalar. Sorun şu ki, bu kitaplıktaki dize verilerini taşıyan işlevler
hedefin taşmasına karşı önlem almayın. Örneğin, şunu düşünün:
strcpy için aşağıdaki çağrı :
strcpy(hedef, kaynak);
Uzunluğu ise dest 20 ve uzunluğu src 50, bir strcpy'nin
dest'i izleyen 30 baytın üzerine yazacaktır . mesele şu ki
strcpy dest uzunluğunu bilmiyor , bu yüzden garanti edemez
takip eden hafızanın üzerine yazılmamasını sağlar. Aynısı
C'deki diğer bazı işlevlerde sorun oluşabilir.
dize kitaplığı. C stili dizelere ek olarak, C++ ayrıca şunları da destekler:
Java'nınkine de benzeyen standart sınıf kitaplığı aracılığıyla dizeler.
C string kitaplığının güvensizlikleri nedeniyle, C++ programcıları
karakter dizileri yerine standart kitaplıktan dize sınıfını kullanın ve
C dize kitaplığı.
Java'da dizeler , değerleri birbirine bağlı olan String sınıfı tarafından desteklenir.
stant dizeleri ve değerleri değişken olan ve StringBuffer sınıfı
daha çok tek karakter dizileri gibi. Bu değerler metotlarla belirtilir.
arasında StringBuffer sınıfına. C# ve Ruby, benzer dize sınıfları içerir
Java'dakilere.
Python, ilkel bir tür olarak dizeleri içerir ve alt dize için işlemlere sahiptir.
tek tek karakterlere erişmek için referans, dizileme, indeksleme ve yöntemler
arama ve değiştirme için. Ayrıca karakter üyesi için bir işlem var-
bir dize gemi. Bu nedenle, Python'un dizeleri ilkel türler olsa da, karakter için
ve alt dize referansları, karakter dizileri gibi davranırlar. Ancak,
Python dizeleri, Java'nın String sınıfı nesnelerine benzer şekilde değişmezdir .
F#'da stringler bir sınıftır. İçinde temsil edilen bireysel karakterler
Unicode UTF-16, erişilebilir, ancak değiştirilemez. Dizeler katener edilebilir
ile + operatörü. ML'de string, ilkel değişmez bir türdür. Bu kullanır ^ için
tarih notu
SNOBOL 4 yaygın olarak kullanılan ilk
pat-
tern eşleştirme.

Sayfa 273
252
Bölüm 6 Veri Tipleri
Katenasyon operatörü ve alt dizi referansı için işlevler içerir ve
bir dize boyutunu almak.
Perl, JavaScript, Ruby ve PHP, yerleşik kalıp eşleştirme işlemlerini içerir.
tion. Bu dillerde, örüntü eşleştirme ifadeleri biraz
gevşek bir şekilde matematiksel düzenli ifadelere dayalıdır. Aslında, genellikle denir
düzenli ifadeler . UNIX'in ilk satır düzenleyicisi olan ed'den evrimleşmişlerdir .
UNIX kabuk dillerinin bir parçası olun. Sonunda, huylarına kadar büyüdüler.
karmaşık formu kiralayın. Bu tür bir model hakkında en az bir eksiksiz kitap var-
eşleşen ifadeler (Friedl, 2006). Bu bölümde, kısa bir bakış sunuyoruz
Bu ifadelerin üslubu nispeten basit iki örnekle.
Aşağıdaki kalıp ifadesini göz önünde bulundurun:
/[A-Za-z][A-Za-z\d]+/
Bu model, programlamadaki tipik ad formuyla eşleşir (veya açıklar).
Diller. Köşeli parantezler karakter sınıflarını kapsar. İlk karakter sınıfı
tüm harfleri belirtir; ikincisi tüm harfleri ve rakamları belirtir (bir rakam belirtilir)
kısaltması ile \d ). Sadece ikinci karakter sınıfı dahil edilmiş olsaydı, biz
bir ismin rakamla başlamasını engelleyemezdi. artı operatör fol-
ikinci kategoriyi düşürmek, olanlardan bir veya daha fazlasının olması gerektiğini belirtir.
kategoride. Böylece, tüm desen bir harfle başlayan dizelerle eşleşir,
ardından bir veya daha fazla harf veya rakam gelir.
Ardından, aşağıdaki kalıp ifadesini göz önünde bulundurun:
/\d+\.?\d*|\.\d+/
Bu model sayısal değişmez değerlerle eşleşir. \ . gerçek bir ondalık nokta belirtir. 3
Soru işareti, sıfır veya bir görünüme sahip olmak için takip eden şeyi nicelleştirir.
Dikey çubuk ( | ) tüm desende iki alternatifi ayırır. İlk
alternatif, bir veya daha fazla basamaktan oluşan dizelerle eşleşir, ardından muhtemelen bir ondalık basamak gelir
nokta, ardından sıfır veya daha fazla rakam; ikinci alternatif dizelerle eşleşir
ondalık nokta ile başlayan, ardından bir veya daha fazla rakam gelen.
Düzenli ifadeler kullanan kalıp eşleştirme yetenekleri,
C++, Java, Python, C# ve F# sınıf kitaplıkları.
6.3.3 Dizi Uzunluğu Seçenekleri
Dize değerlerinin uzunluğuyla ilgili birkaç tasarım seçeneği vardır. Öncelikle,
uzunluk statik olabilir ve dize oluşturulduğunda ayarlanabilir. Böyle bir dize
statik uzunluklu dize denir . Python dizileri için seçim budur,
Java'nın String sınıfının değişmez nesneleri ve C++'daki benzer sınıflar
standart sınıf kitaplığı, Ruby'nin yerleşik String sınıfı ve .NET sınıf kitaplığı
C# ve F# için kullanılabilir.
3. Nokta ters eğik çizgi ile “kaçınılmalıdır” çünkü noktanın bir terimde özel bir anlamı vardır.
Düzenli ifade.

Sayfa 274
6.3 Karakter Dizisi Türleri 253
İkinci seçenek, dizelerin belirli bir uzunluğa kadar değişen uzunluklara sahip olmasına izin vermektir.
örneklendiği gibi, değişkenin tanımına göre bildirilen ve sabit maksimum ayar
C'deki dizeler ve C++'ın C stili dizeleri tarafından. Bunlara sınırlı denir
dinamik uzunluk dizeleri . Bu tür dize değişkenleri herhangi bir sayıda karakter saklayabilir.
sıfır ile maksimum arasındaki aktörler. C'deki dizelerin özel bir
korumak yerine dizenin karakterlerinin sonunu belirtmek için karakter
dize uzunluğu.
Üçüncü seçenek, dizelerin maksimum uzunluk olmadan değişen uzunluklara sahip olmasına izin vermektir.
anne, JavaScript, Perl ve standart C++ kitaplığında olduğu gibi. Bunlara denir
dinamik uzunluk dizeleri . Bu seçenek, dinamik depolamanın ek yükünü gerektirir
tahsis ve serbest bırakma, ancak maksimum esneklik sağlar.
Ada 95+, üç dizi uzunluğu seçeneğini de destekler.
6.3.4 Değerlendirme
Dize türleri, bir dilin yazılabilirliği için önemlidir. Dizelerle uğraşmak
çünkü diziler, ilkel bir dize türüyle uğraşmaktan daha hantal olabilir.
Örneğin, dizeleri karakter dizileri olarak ele alan bir dil düşünün.
ve C'de strcpy'nin yaptığını yapan önceden tanımlanmış bir işlevi yoktur.
Ardından, bir dizenin diğerine basit bir şekilde atanması bir döngü gerektirir. bu
Bir dile ilkel bir tür olarak dizelerin eklenmesi, aşağıdakiler açısından maliyetli değildir.
dil veya derleyici karmaşıklığı. Bu nedenle, haklı çıkarmak zor
bazı çağdaş dillerde ilkel dize türlerinin ihmali. Tabii ki,
standart bir kitaplık aracılığıyla dizeleri sağlamak, neredeyse
ilkel bir tür olarak onları.
Basit örüntü eşleştirme ve katenasyon gibi dizge işlemleri
önemlidir ve dize türü değerleri için dahil edilmelidir. Her ne kadar dinamik-
uzunluk dizileri açıkçası en esnek olanlardır, bunların uygulanmasının genel giderleri
bu ek esnekliğe karşı tartılmalıdır.
6.3.5 Karakter Dizisi Türlerinin Uygulanması
Karakter dizisi türleri doğrudan donanımda desteklenebilir; ama çoğunda
durumlarda, dizi depolama, alma ve manipülasyon uygulamak için yazılım kullanılır.
Karakter dizisi türleri karakter dizileri olarak temsil edildiğinde, dil
genellikle birkaç işlem sağlar.
Yalnızca sırasında gerekli olan statik karakter dizesi türü için bir tanımlayıcı.
derleme, üç alana sahiptir. Her tanımlayıcının ilk alanı isimdir.
türden. Statik karakter dizileri durumunda, ikinci alan türün
uzunluk (karakter olarak). Üçüncü alan, ilk karakterin adresidir. Bu
tanımlayıcı Şekil 6.2'de gösterilmiştir. Sınırlı dinamik dizeler bir çalışma zamanı gerektirir
hem sabit maksimum uzunluğu hem de mevcut uzunluğu saklamak için tanımlayıcı,
Şekil 6.3'te gösterildiği gibi. Dinamik uzunluk dizileri daha basit bir çalışma zamanı gerektirir
tanımlayıcı, çünkü yalnızca geçerli uzunluğun saklanması gerekir. Bize ragmen
tanımlayıcıları bağımsız depolama blokları olarak tasvir eder, çoğu durumda bunlar
sembol tablosunda saklanır.

Sayfa 275
254
Bölüm 6 Veri Tipleri
C ve C++'ın sınırlı dinamik dizileri, çalışma zamanı tanımlamasını gerektirmez.
tors, çünkü bir dizenin sonu boş karakterle işaretlenmiştir. Onlar yapar
maksimum uzunluğa ihtiyaç duymaz, çünkü dizi referanslarındaki indeks değerleri
Bu dillerde aralık kontrol edildi.
Statik uzunluk ve sınırlı dinamik uzunluk dizileri özel bir dinamik gerektirmez
depolama tahsisi. Sınırlı dinamik uzunluklu diziler durumunda, yeterli depolama
dize değişkeni bağlı olduğunda maksimum uzunluk için yaş tahsis edilir
depolama, bu nedenle yalnızca tek bir tahsis süreci söz konusudur.
Dinamik uzunluk dizileri, daha karmaşık depolama yönetimi gerektirir. bu
bir dizinin uzunluğu ve dolayısıyla bağlı olduğu depolama alanı büyümelidir.
ve dinamik olarak küçülür.
Dinamik tahsisi ve anlaşmayı desteklemek için üç yaklaşım vardır.
dinamik uzunluk dizileri için gerekli olan konum. İlk olarak, dizeler saklanabilir
bağlantılı bir listede, böylece bir dize büyüdüğünde, yeni gerekli hücreler gelebilir
yığının herhangi bir yerinden. Bu yöntemin dezavantajları ekstra depolama alanıdır.
liste gösterimindeki bağlantılar ve gerekli karmaşıklık tarafından işgal edilir
dize işlemlerinden oluşur.
İkinci yaklaşım, dizeleri bireysel işaretçi dizileri olarak depolamaktır.
yığında tahsis edilen karakterler. Bu yöntem hala fazladan bellek kullanır, ancak dize
işleme, bağlantılı liste yaklaşımından daha hızlı olabilir.
Üçüncü alternatif, tam dizileri bitişik depoda saklamaktır.
hücreler. Bu yöntemle ilgili sorun, bir dize büyüdüğünde ortaya çıkar: Nasıl
mevcut hücrelere bitişik olan depolama alanı için tahsis edilmeye devam edilir.
dizi değişkeni? Sıklıkla, böyle bir depolama mevcut değildir. Bunun yerine yeni bir alan
yeni dizenin tamamını ve eski bölümü depolayabilen bellek bulundu
bu alana taşınır. Daha sonra eski dizi için kullanılan bellek hücreleri işlenir.
yer alır. Bu ikinci yaklaşım tipik olarak kullanılandır. genel sorun
değişken büyüklükteki bölümlerin tahsisini ve tahsisini yönetme konusu tartışıldı
Bölüm 6.11.8.3'te.
Bağlantılı liste yöntemi daha fazla depolama gerektirse de, ilişkili
tahsis ve serbest bırakma süreçleri basittir. Ancak, bazı dize
Şekil 6.2
Derleme zamanı tanımlayıcısı
statik dizeler için
statik dize
Uzunluk
Adres
Şekil 6.3
için çalışma zamanı tanımlayıcısı
sınırlı dinamik diziler
Sınırlı dinamik dize
Maksimum uzunluk
Mevcut uzunluk
Adres

Sayfa 276
6.4 Kullanıcı Tanımlı Sıra Türleri 255
işlemler, gerekli işaretçi takibi tarafından yavaşlatılır. Diğer taraftan,
tam dizeler için bitişik belleğin kullanılması daha hızlı dize işlemleriyle sonuçlanır
ve önemli ölçüde daha az depolama gerektirir, ancak tahsis ve serbest bırakma pro-
teneffüsler daha yavaştır.
6.4 Kullanıcı Tanımlı Sıra Türleri
Bir sıra tip olası değerler aralığı kolayca hangi biri
pozitif tamsayılar kümesi ile ilişkilidir. Örneğin Java'da ilkel
sıra türleri tamsayı , karakter ve boole . iki kullanıcı tanımlı
programlama dilleri tarafından desteklenen sıra türleri: numaralandırma-
tion ve alt aralığı.
6.4.1 Numaralandırma Türleri
Bir numaralandırma türü , olası tüm değerlerin olduğu bir türdür.
adlandırılmış sabitler, tanımda sağlanır veya numaralandırılır. numaralandırma
türleri, adlandırılmış sabitlerin koleksiyonlarını tanımlamanın ve gruplandırmanın bir yolunu sağlar,
bunlara numaralandırma sabitleri denir . Tipik bir numaralandırmanın tanımı-
tion tipi aşağıdaki C# örneğinde gösterilmiştir:
enum gün {Pzt, Sal, Çar, Per, Cum, Cts, Paz};
Numaralandırma sabitleri tipik olarak örtük olarak tamsayıya atanır.
değerler, 0, 1, . . . ancak türün herhangi bir tamsayı değişmezine açıkça atanabilir
tanım.
Numaralandırma türleri için tasarım sorunları aşağıdaki gibidir:
• Bir numaralandırma sabitinin birden fazla tip tanımında görünmesine izin veriliyor mu?
ve eğer öyleyse, bu sabitin oluşum tipi nasıldır?
program kontrol edildi mi?
• Numaralandırma değerleri tamsayıya zorlanıyor mu?
• Bir numaralandırma türüne zorlanan başka türler var mı?
Tüm bu tasarım sorunları, tip kontrolü ile ilgilidir. Eğer bir numaralandırma
değişken sayısal bir türe zorlanır, o zaman aralığı üzerinde çok az kontrol vardır
yasal işlemler veya değer aralığı. Bir int türü değeri bir
numaralandırma türü, daha sonra herhangi bir numaralandırma türü değişkenine atanabilir
bir numaralandırma sabitini temsil edip etmediğini tamsayı değeri.
6.4.1.1 Tasarımlar
Numaralandırma türü olmayan dillerde, programcılar genellikle simu-
onları tamsayı değerleriyle geç. Örneğin, temsil etmemiz gerektiğini varsayalım.
C programında ve C'de renkler bir numaralandırma tipine sahip değildi. kullanabiliriz

Sayfa 277
256
Bölüm 6 Veri Tipleri
0 maviyi temsil eder, 1 kırmızıyı temsil eder vb. Bu değerler olabilir
aşağıdaki gibi tanımlanır:
int kırmızı = 0, mavi = 1;
Şimdi, programda kırmızı ve maviyi sanki bir
renk türü. Bu yaklaşımla ilgili sorun şu ki,
renklerimiz için bir tip tanımladılar, kullanıldıklarında tip kontrolü yok.
Örneğin, ikisini bir araya getirmek yasal olacaktır, ancak bu
nadiren amaçlanan bir işlem olabilir. Ayrıca herhangi biriyle birleştirilebilirler.
herhangi bir aritmetik işleç kullanan başka bir sayısal tür işlenen
ayrıca nadiren yararlı olabilir. Ayrıca, sadece değişken oldukları için
herhangi bir tamsayı değeri atanabilir, böylece ilişkiyi yok eder
renklerle. Bu son sorun, onları yaparak önlenebilirdi.
adlandırılmış sabitler.
C ve Pascal, bir numaralandırma içeren ilk yaygın olarak kullanılan dillerdi.
veri türü. C++, C'nin numaralandırma türlerini içerir. C++'da,
Takip etmek:
numaralandırma renkleri {kırmızı, mavi, yeşil, sarı, siyah};
renkler myColor = mavi, yourColor = kırmızı;
Renkler tipi numaralandırma kon- için varsayılan dahili değerleri kullanır
stantlar, 0, 1, . . . , sabitlere herhangi bir tamsayı atanmış olsa da
değişmez (veya herhangi bir sabit değerli ifade). Numaralandırma değerleri zorlanır
için int bunlar tam sayı bağlamında konduklarında. Bu, herhangi bir yerde kullanımlarına izin verir.
sayısal ifade. Örneğin, mevcut değeri ise myColor olan mavi ,
sonra ifade
benimRenk++
atayın yeşil için myColor .
C++ ayrıca numaralandırma sabitlerinin herhangi bir değişkene atanmasına izin verir.
sayısal tür, ancak bu muhtemelen bir hata olacaktır. Ancak başka hiçbir tür
değer, C++'da bir numaralandırma türüne zorlanır. Örneğin,
benimRenk = 4;
C++'da yasa dışıdır. Sağ taraf atılmış olsaydı bu atama yasal olurdu
için renkler tip. Bu, bazı olası hataları önler.
C++ numaralandırma sabitleri, yalnızca bir numaralandırma türünde görünebilir.
aynı referans ortamı.
Ada'da, numaralandırma değişmezlerinin birden fazla yerde görünmesine izin verilir.
aynı referans ortamında beyan. Bunlara aşırı denir
yüklü değişmezler . Aşırı yüklemeyi çözme kuralı—yani, karar verme
Böyle bir değişmezin meydana gelme türü - belirlenebilir olması gerektiğidir.

Sayfa 278
6.4 Kullanıcı Tanımlı Sıra Türleri 257
görünüşü bağlamından. Örneğin, aşırı yüklenmiş bir hazır bilgi
ve bir numaralandırma değişkeni karşılaştırılır, değişmezin türü şu şekilde çözülür:
değişkeninki olsun. Bazı durumlarda, programcı bazı
bir iletişimden kaçınmak için aşırı yüklenmiş bir hazır bilgi oluşumu için tür belirtimi
pilasyon hatası
Çünkü ne numaralandırma değişmezleri ne de numaralandırma değişkenleri
Ada'da, hem işlem aralığı hem de işlem aralığı olan tam sayılara zorlanır.
numaralandırma türlerinin değerleri kısıtlanmıştır, bu da birçok programcı hatasına izin verir
derleyici algılanacak.
2004'te Java 5.0'da Java'ya bir numaralandırma türü eklendi. tüm numaralandırma-
Java'daki tion türleri, önceden tanımlanmış Enum sınıfının örtük olarak alt sınıflarıdır . Çünkü
numaralandırma türleri sınıflardır, örnek veri alanlarına, yapıcılara,
ve yöntemler. Sözdizimsel olarak, Java numaralandırma türü tanımları şu şekilde görünür:
alanları, yapıcıları ve yöntemleri içerebilmeleri dışında C++'ın bu
bir numaralandırmanın olası değerleri, sınıfın tek olası örnekleridir.
Tüm numaralandırma türleri , birkaç başka yöntemin yanı sıra toString öğesini devralır . Bir
bir numaralandırma türünün örneklerinin dizisi, statik ile getirilebilir
yöntem değerleri . Bir numaralandırma değişkeninin dahili sayısal değeri,
sıralı yöntemle getirilebilir . Başka türden hiçbir ifade olamaz
bir numaralandırma değişkenine atanır. Ayrıca, bir numaralandırma değişkeni asla
başka bir türe zorladı.
C# numaralandırma türleri, hiçbir zaman
tamsayıya zorlanır. Bu nedenle, numaralandırma türleri üzerindeki işlemler bunlarla sınırlıdır.
bu mantıklı. Ayrıca, değer aralığı belirli bir değer aralığıyla sınırlıdır.
numaralandırma türü.
ML'de, numaralandırma türleri, veri türü azalmasıyla yeni türler olarak tanımlanır.
larasyonlar. Örneğin, aşağıdakilere sahip olabiliriz:
veri türü hafta içi = Pazartesi | Salı | Çarşamba |
Perşembe | Cuma
Hafta içi günlerin elemanlarının türleri tamsayıdır.
F#, ML'ninkilere benzer numaralandırma türlerine sahiptir;
veri türü yerine ayrılmış sözcük türü kullanılır ve ilk değerden önce gelir
VEYA operatörü tarafından ( | ).
İlginç bir şekilde, nispeten yeni komut dosyası türlerinden hiçbiri
numaralandırma türlerini içerir. Bunlar Perl, JavaScript, PHP, Python,
Ruby ve Lua. Java bile numaralandırma türlerinden on yıl önceydi
eklendi.
6.4.1.2 Değerlendirme
Numaralandırma türleri, hem okunabilirlik hem de güvenilirlik açısından avantajlar sağlayabilir.
ıt. Okunabilirlik doğrudan iyileştirilir: Adlandırılmış değerler kolayca tanınır,
kodlanmış değerler ise değildir.

Sayfa 279
258
Bölüm 6 Veri Tipleri
Güvenilirlik alanında Ada, C#, F# ve Java'nın numaralandırma türleri
5.0 iki avantaj sağlar: (1) Hesaplamada hiçbir aritmetik işlem yasal değildir.
merasyon türleri; bu, örneğin haftanın günlerini eklemeyi önler ve
(2) ikinci olarak, hiçbir numaralandırma değişkenine tanımlananın dışında bir değer atanamaz
Aralık. 4 Eğer renkler numaralandırma türü 10 numaralandırma sabitleri vardır ve
0..9'u dahili değerler olarak kullanır , 9'dan büyük bir sayı atanamaz
bir renk türü değişkeni.
C, numaralandırma değişkenlerini tamsayı değişkenleri gibi ele aldığından,
bu iki avantajdan birini sağlar.
C++ biraz daha iyidir. Numaralandırma tipine sayısal değerler atanabilir
değişkenler, yalnızca atanan değişkenin türüne dönüştürülmeleri durumunda. sayısal değer
numaralandırma türü değişkenlerine atanan u'lar, olup olmadığını belirlemek için kontrol edilir.
numaralandırma türünün iç değerlerinin aralığındadırlar. talihsiz-
doğal olarak, kullanıcı çok çeşitli açıkça atanmış değerler kullanıyorsa, bu kontrol
etkili değildir. Örneğin,
enum renkleri {kırmızı = 1, mavi = 1000, yeşil = 100000}
Bu örnekte, renk türündeki bir değişkene atanan değer yalnızca
1..100000 aralığında olup olmadığı kontrol edilir .
6.4.2 Alt Aralık Türleri
Bir alt aralık türü , sıralı bir türün bitişik bir alt dizisidir . Örneğin,
12..14 tamsayı türünün bir alt aralığıdır . Alt aralık türleri tarafından tanıtıldı
Pascal ve Ada dahildir. Belirli bir tasarım sorunu yoktur.
alt aralık türleri.
6.4.2.1 Ada'nın Tasarımı
Ada'da alt aralıklar, alt türler adı verilen tür kategorisine dahil edilir. olduğu gibi
Bölüm 5'te belirtildiği gibi, alt tipler yeni tipler değildir; daha doğrusu, onlar yeni isimler
mevcut türlerin muhtemelen kısıtlanmış veya kısıtlanmış sürümleri için. Örneğin,
aşağıdaki beyanları dikkate alın:
tip Günleri ise (Pazartesi, Salı, Çarşamba, Perşembe, Cuma, Cumartesi, Pazar);
alt tip Hafta içi Gün aralığı Pzt..Cum;
alt tür İndeks : Tamsayı aralığı 1..100;
Bu örneklerde, mevcut tipler üzerindeki kısıtlama, aşağıdakiler aralığındadır:
olası değerler. Ana tip için tanımlanan tüm işlemler de tanımlanmıştır.
4. C# ve F#'da, bir tamsayı değeri bir numaralandırma tipine dönüştürülebilir ve isme atanabilir.
bir numaralandırma değişkeninin Bu tür değerler Enum.IsDefined yöntemiyle test edilmelidir.
onları bir numaralandırma değişkeninin adına atamadan önce.

Sayfa 280
6.5 Dizi Türleri 259
alt tip için, belirtilen aralığın dışındaki değerlerin atanması dışında. İçin
örnek, içinde
1. Gün : Günler;
2. Gün : Hafta içi;
. . .
2. Gün := 1. Gün;
Atama, Day1'in değeri Sat veya Sun olmadığı sürece yasaldır .
Derleyici, her atama için aralık kontrol kodu üretmelidir.
bir alt aralık değişkeni. Türler derleme zamanında uyumluluk açısından kontrol edilirken,
alt aralıklar, çalışma zamanı aralığı denetimi gerektirir.
Kullanıcı tanımlı sıra türlerinin en yaygın kullanımlarından biri,
Bölüm 6.5'te tartışılacağı gibi dizilerin indeksleri. Onlar için de kullanılabilirler
döngü değişkenleri. Aslında, sıralı türlerin alt aralıkları, aralığın tek yoludur.
Ada for döngü değişkenleri belirtilebilir.
6.4.2.2 Değerlendirme
Alt aralık türleri, okuyuculara değişkenlerin
alt türler yalnızca belirli değer aralıklarını saklayabilir. ile güvenilirlik artar
alt aralık türleri, çünkü dışarıdaki bir alt aralık değişkenine bir değer atamak
belirtilen aralık, derleyici tarafından bir hata olarak algılanır (
atanan değer gerçek bir değerdir) veya çalışma zamanı sistemi tarafından (durumda
bir değişkenin veya ifadenin). dışında hiçbir çağdaş dilin olmaması tuhaftır.
Ada'nın alt aralık türleri vardır.
6.4.3 Kullanıcı Tanımlı Sıra Türlerinin Uygulanması
Daha önce tartışıldığı gibi, numaralandırma türleri genellikle tamsayılar olarak uygulanır.
Değer aralıkları ve işlemler üzerinde kısıtlama olmaksızın, bu,
güvenilirlikte artış.
Alt aralık türleri, üst öğeleriyle tam olarak aynı şekilde uygulanır
türler dışında, aralık kontrolleri derleyici tarafından örtük olarak dahil edilmelidir.
bir değişkenin veya ifadenin bir alt aralık değişkenine her ataması. Bu adım
kod boyutunu ve yürütme süresini artırır, ancak genellikle buna değer olarak kabul edilir.
maliyet. Ayrıca, iyi bir optimizasyon derleyicisi, kontrollerin bir kısmını optimize edebilir.
6.5 Dizi Türleri
Bir dizi , içinde bir bireyin bulunduğu homojen bir veri öğeleri toplamıdır.
eleman, ilk öğeye göre toplamdaki konumu ile tanımlanır.
ment. Bir dizinin tek tek veri öğeleri aynı tiptedir. Referanslar
bireysel dizi öğelerine, alt simge ifadeleri kullanılarak belirtilir. eğer herhangi biri
bir referanstaki alt simge ifadeleri değişkenleri içerir, ardından referans

Sayfa 281
260
Bölüm 6 Veri Tipleri
adresini belirlemek için ek bir çalışma zamanı hesaplaması gerektirecektir.
başvurulan bellek konumu.
C, C++, Java, Ada ve C# gibi birçok dilde tüm öğeler
bir dizinin aynı türden olması gerekir. Bu dillerde işaretçiler ve
referanslar, tek bir tipe işaret etmek veya referans vermekle sınırlıdır. Yani nesneler veya
işaret edilen veya başvurulan veri değerleri de tek tiptir. diğer bazılarında
JavaScript, Python ve Ruby gibi dillerde değişkenler türsüz referanslardır.
nesnelere veya veri değerlerine. Bu durumlarda, diziler hala tek bir dizinin elemanlarından oluşur.
yazın, ancak öğeler nesnelere veya farklı türlerdeki veri değerlerine başvurabilir. Çok
dizi elemanları aynı tipte olduğu için diziler hala homojendir.
C# ve Java 5.0, genel diziler sağlar, yani öğeleri
sınıf kitaplıkları aracılığıyla nesnelere yapılan referanslardır. bunlar şurada tartışılıyor
Bölüm 6.5.3.
6.5.1 Tasarım Konuları
Dizilere özgü birincil tasarım sorunları şunlardır:
• Abonelikler için hangi türler yasaldır?
• Öğe referansları aralığındaki abonelik ifadeleri kontrol ediliyor mu?
• Alt simge aralıkları ne zaman bağlanır?
• Dizi tahsisi ne zaman gerçekleşir?
• Düzensiz veya dikdörtgen çok boyutlu dizilere veya her ikisine de izin veriliyor mu?
• Diziler, depoları tahsis edildiğinde başlatılabilir mi?
• Varsa ne tür dilimlere izin verilir?
Aşağıdaki bölümlerde, tasarım için yapılan tasarım seçimlerinin örnekleri,
en yaygın programlama dillerinin dizileri tartışılmaktadır.
6.5.2 Diziler ve İndeksler
Bir dizinin belirli öğelerine iki seviyeli bir sözdizimi aracılığıyla başvurulur.
mekanizma, burada birinci kısım toplam isim ve ikinci kısım bir
alt simge olarak bilinen bir veya daha fazla öğeden oluşan muhtemelen dinamik seçici
veya endeksler . Bir referanstaki tüm indisler sabitse, seçici
statik; aksi halde dinamiktir. Seçim işlemi olabilir
dizi adından ve alt kümesinden bir eşleme olarak düşünülür.
toplamdaki bir öğeye komut dosyası değerleri. Nitekim diziler
bazen sonlu eşlemeler olarak adlandırılır . Bu haritalama sembolik olarak
olarak gösterilebilir
dizi_adı(alt simge_değer_listesi) → eleman
Dizi referanslarının sözdizimi oldukça evrenseldir: Dizi
adının ardından, etrafı çevrili olan abonelikler listesi gelir.
parantez veya parantez ile. Bazı dillerde pro-
çok boyutlu dizileri dizi dizileri olarak görüntüle, her bir alt simge
tarih notu
90 öncesi tasarımcılar-
trans ve PL/I ebeveyn-
dizi abonelikleri için tezler
çünkü başka uygun değil
karakterler mevcuttu
zaman. Kart yumrukları olmadı
parantez karakterlerini içerir.

Sayfa 282
6.5 Dizi Tipleri 261
kendi parantezlerinde görünür. Parantez kullanımıyla ilgili bir sorun
alt simge ifadelerini dahil etmek için genellikle aynı zamanda kullanılırlar.
parametreleri alt program çağrılarına dahil etmek; bu kullanım yapar
dizilere yapılan başvurular tam olarak bu çağrılar gibi görünür. Örneğin,
aşağıdaki Ada atama ifadesini göz önünde bulundurun:
Toplam := Toplam + B(I);
Parantezler her iki alt program parametresi için kullanıldığından
ve Ada'daki dizi aboneleri, hem program okuyucuları hem de derleyiciler
B(I) olup olmadığını belirlemek için diğer bilgileri kullanmak zorunda kalırlar.
bu atamada bir fonksiyon çağrısı veya bir dizi elemanına yapılan bir başvurudur.
ment. Bu, okunabilirliğin azalmasına neden olur.
Ada'nın tasarımcıları özellikle parantezleri seçti.
dizi arasında tekdüzelik olması için abonelikleri içine alın
potansiyele rağmen, ifadelerdeki referanslar ve işlev çağrıları
okunabilirlik sorunları Bu seçimi kısmen yaptılar çünkü ikisi de
dizi öğesi başvuruları ve işlev çağrıları eşlemelerdir. Sıralamak
öğe referansları, abonelikleri belirli bir öğeye eşler.
dizi. İşlev çağrıları, gerçek parametreleri işleve eşler.
tanım ve nihayetinde işlevsel bir değer.
Fortran ve Ada dışındaki çoğu dil,
dizi indekslerini sınırlandırın.
Bir dizi tipinde iki farklı tip yer alır: eleman tipi ve
alt simge türü. Alt simgelerin türü, genellikle,
gers, ancak Ada, Boolean gibi herhangi bir sıra türünün abonelik olarak kullanılmasına izin verir,
karakter ve numaralandırma. Örneğin, Ada'da şunlar olabilir:
tip Week_Day_Type olan (Pazartesi, Salı, Çarşamba,
Perşembe Cuma);
Satış türü , Float'ın dizisidir (Week_Day_Type);
Bir Ada for döngüsü, sayacı için herhangi bir sıra tipi değişkeni kullanabilir, çünkü biz
Bölüm 8'de görülecektir. Bu, sıralı tip alt simgeleri olan dizilerin
uygun şekilde işlenir.
Erken programlama dilleri, alt simge aralıklarının olması gerektiğini belirtmedi.
dolaylı olarak kontrol edilmelidir. Aboneliklerdeki aralık hataları programlarda yaygındır, bu nedenle
menzil kontrolü gerektirmesi, dillerin güvenilirliğinde önemli bir faktördür.
Birçok çağdaş dil, aboneliklerin aralık kontrolünü belirtmez, ancak
Java, ML ve C# yapar. Varsayılan olarak Ada, tüm aboneliklerin aralığını kontrol eder, ancak bu
özellik programcı tarafından devre dışı bırakılabilir.
Perl'de abone olmak biraz sıra dışıdır, çünkü tüm dizilerin adları
( @ ) ile başlayın , çünkü dizi elemanları her zaman skalerdir ve
skalerler her zaman dolar işaretiyle ( $ ) başlar, dizi öğelerine yapılan başvurularda dolar kullanılır
adlarındaki işaretlerden ziyade işaretler. Örneğin, @list dizisi için ,
ikinci öğeye $list [1] ile başvurulur .
tarih notu
Fortran sayıyı sınırladım
dizi aboneliklerinin üçe,
çünkü zamanında
tasarım, yürütme verimliliği
birincil bir endişe. Fortran
Ben tasarımcılar geliştirmiştim
erişim için çok hızlı bir yöntem
up dizilerinin elemanları
kullanılarak üç boyuta
IBM'in üç dizin kaydı
704. Fortran IV ilk kez uygulandı-
IBM 7094'te belirtilen,
yedi indeks kaydı vardı. Bu
Fortran IV'ün tasarımcılarına izin verildi
yediye kadar dizilere izin vermek için
abonelikler. Diğer çoğu düşünce-
porary dilleri hayır zorlar
böyle sınırlar.

Sayfa 283
262
Bölüm 6 Veri Tipleri
Perl'de bir dizi öğesine negatif bir alt simge ile başvurulabilir,
bu durumda alt simge değeri dizinin sonundan bir uzaklıktır. Sınav için-
ple, eğer @list dizisinin 0..4, $list [-2] indislerine sahip beş elemanı varsa
öğeye alt simge 3 ile başvurur. Var olmayan bir öğeye başvuru.
Perl'deki ment, undef değerini verir , ancak hiçbir hata bildirilmez.
6.5.3 Alt Simge Bağlamaları ve Dizi Kategorileri
Alt simge türünün bir dizi değişkenine bağlanması genellikle statiktir, ancak
alt simge değer aralıkları bazen dinamik olarak bağlıdır.
Bazı dillerde, alt simge aralığının alt sınırı örtüktür. İçin
örneğin, C tabanlı dillerde, tüm alt simge aralıklarının alt sınırı
0'da sabit ; Fortran 95+'da varsayılan olarak 1'dir, ancak herhangi bir tamsayı değişmezine ayarlanabilir.
Diğer bazı dillerde, alt simge aralıklarının alt sınırları şu şekilde olmalıdır:
programcı tarafından belirlenir.
Alt simgeye bağlanmaya dayalı olarak beş dizi kategorisi vardır.
aralıklar, depolamaya bağlanma ve depolamanın tahsis edildiği yerden. bu
kategori adları bu üçünün tasarım seçimlerini gösterir. ilk dördünde
bu kategoriler, alt simge aralıkları bağlandıktan ve depolama ayrıldıktan sonra
olarak, değişkenin ömrü boyunca sabit kalırlar. unutmayın ki ne zaman
alt simge aralıkları sabittir, dizi boyutu değiştiremez.
Bir statik bir dizi alt simge aralıkları statik bağlı olduğu bir dengedir
ve depolama tahsisi statiktir (çalışma zamanından önce yapılır). Statik olmanın avantajı
diziler verimliliktir: Dinamik ayırma veya ayırma gerekmez. bu
dezavantaj, dizinin depolamasının tüm yürütme için sabitlenmiş olmasıdır.
programın zamanı.
Bir sabit yığın dinamik bir dizi olan indis aralıkları olan bir stati- olan
kesin olarak bağlı, ancak tahsis, beyan detaylandırma zamanında yapılır.
uygulamak. Sabit yığın dinamik dizilerin statik dizilere göre avantajı boşluktur
yeterlik. Bir alt programdaki büyük bir dizi, büyük bir diziyle aynı alanı kullanabilir
Her iki alt program aynı anda aktif olmadığı sürece farklı bir alt programda
zaman. Aynısı, iki dizi de aktif olmayan farklı bloklardaysa geçerlidir.
Aynı zaman. Dezavantajı, gerekli tahsis ve tahsis süresidir.
Bir yığın dinamik bir dizi olan indis aralıkları ve hem de biridir
depolama tahsisi, detaylandırma zamanında dinamik olarak bağlanır. Bir kez alt-
komut dosyası aralıkları bağlanır ve depolama ayrılır, ancak sabit kalırlar
değişkenin ömrü boyunca. Yığın dinamik dizilerin avantajı
statik ve sabit yığın dinamik diziler esnekliktir. Bir dizinin boyutunun olması gerekmez
dizi kullanılmak üzere olana kadar bilinmelidir.
Bir sabit yığın dinamik bir dizi olup, sabit bir yığın dinamik dizisine benzer olduğunu
hem alt simge aralıkları hem de depolama bağlaması, depolama ayrıldıktan sonra sabitlenir.
Farklar, hem alt simge aralıklarının hem de depolama bağlamalarının yapılmasıdır.
kullanıcı programı yürütme sırasında bunları istediğinde ve depolama
yığından ziyade yığından alınır. Sabit yığın dinamiğinin avantajı
diziler esnekliktir—dizinin boyutu her zaman soruna uyar. dezavantajı
yığından ayırma süresinden daha uzun olan yığından ayırma süresi.

Sayfa 284
6.5 Dizi Türleri 263
Bir yığın dinamik dizi indis aralıkları bağlanması olan bir ve
depolama tahsisi dinamiktir ve işlem sırasında herhangi bir sayıda değişebilir.
dizinin ömrü. Yığın dinamik dizilerin diğerlerine göre avantajı esnek-
uygunluk: Diziler, program yürütme sırasında ihtiyaç duyulduğundan büyüyebilir ve küçülebilir.
uzay değişir. Dezavantajı, tahsis ve tahsisin daha uzun sürmesidir.
ve programın yürütülmesi sırasında birçok kez olabilir. Örnekler
Aşağıdaki paragraflarda beş kategori verilmiştir.
Statik değiştiriciyi içeren C ve C++ işlevlerinde bildirilen diziler
statiktir.
C ve C++ işlevlerinde bildirilen diziler ( statik
belirteci), sabit yığın dinamik dizilerin örnekleridir.
Ada dizileri, aşağıdaki gibi yığın dinamik olabilir:
Get(List_Len);
bildirmek
Listesi: dizi (1..List_Len) arasında bir tamsayı;
başlamak
. . .
son ;
Bu örnekte, kullanıcı dizi için istenen eleman sayısını girer.
Liste . Öğeler daha sonra yürütme ulaştığında dinamik olarak tahsis edilir.
beyan bloğu. Yürütme bloğun sonuna ulaştığında, Liste
dizi serbest bırakıldı.
C ve C++ ayrıca sabit yığın dinamik diziler sağlar. standart C kitaplığı
genel yığın tahsisi ve serbest yerleşim olan malloc ve free işlevleri
C dizileri için sırasıyla tion işlemleri kullanılabilir. C++ operatörleri kullanır
yığın depolamayı yönetmek için yeni ve sil . Bir dizi, bir işaretçi olarak kabul edilir.
bölümünde tartışıldığı gibi, işaretçinin dizine eklenebileceği bir depolama hücreleri koleksiyonu
Bölüm 6.11.5.
Java'da, genel olmayan tüm diziler sabit yığın dinamiktir. Bir kez oluşturulduktan sonra, bunlar
diziler aynı alt simge aralıklarını ve depolamayı korur. C# da aynısını sağlar
tür diziler.
C# ayrıca, nesnenin nesneleri olan genel yığın dinamik diziler sağlar.
Liste sınıfı. Bu dizi nesneleri, aşağıdaki gibi herhangi bir öğe olmadan oluşturulur.
List<String> stringList = new List<String>();
Öğeler , aşağıdaki gibi Add yöntemiyle bu nesneye eklenir .
stringList.Add("Michael");
Bu dizilerin öğelerine erişim, abonelik yoluyla olur.
Java, ArrayList adlı C#'s List'e benzer bir genel sınıf içerir . Bu
C# Listesinden farklı olarak , bu abonelik desteklenmez— get and set
öğelere erişmek için yöntemler kullanılmalıdır.

Sayfa 285
264
Bölüm 6 Veri Tipleri
Push kullanılarak bir Perl dizisi büyütülebilir ( bir veya daha fazla
dizinin sonundaki yeni öğeler) ve unshift (bir veya daha fazla yeni öğe koyar )
dizinin başlangıcındaki öğeler) veya diziye bir değer atayarak
dizinin mevcut en yüksek alt indisinin ötesinde bir indis belirtmek. Bir
dizi, boş liste atayarak hiçbir öğeye küçültülemez () .
Bir dizinin uzunluğu, en büyük alt simge artı bir olarak tanımlanır.
Perl gibi JavaScript de dizilerin push ve unshift ile büyümesine izin verir.
yöntemleri ve bunları boş listeye ayarlayarak küçültün. Ancak olumsuz alt
komut dosyaları desteklenmez.
JavaScript dizileri seyrek olabilir, yani alt simge değerlerinin olması gerekmez
bitişik. Örneğin, 10 elemanlı list adında bir dizimiz olduğunu varsayalım.
0..9 indisleri ile ifadeler. 5 Aşağıdaki atama ifadesini inceleyin:
liste[50] = 42;
Şimdi, listede 11 eleman var ve 51 uzunluk var.
11..49 tanımlı değildir ve bu nedenle depolama gerektirmez. Bir referans
JavaScript dizisindeki var olmayan öğe, undefined sonucunu verir .
Python, Ruby ve Lua'daki diziler yalnızca metotla büyütülebilir.
ods öğeleri eklemek veya diğer dizileri sıralamak için. Ruby ve Lua negatifi destekliyor
abonelikler, ancak Python yok. Python, Ruby ve Lua'da bir eleman veya dilim
bir dizi silinebilir. Python'da var olmayan bir öğeye başvuru
bir çalışma zamanı hatasıyla sonuçlanırken, Ruby ve Lua'daki benzer bir referans verim sağlar
sıfırdır ve hata bildirilmez.
ML tanımı dizileri içermemesine rağmen, yaygın olarak kullanılan uygulamasıdır.
akıl yürütme, SML/NJ, yapar.
F#'ın parçası olan tek önceden tanımlanmış koleksiyon türü dizidir (diğer
koleksiyon türleri .NET Framework Kitaplığı aracılığıyla sağlanır). Bunlar
diziler C# dizileri gibidir. Dile bir foreach ifadesi dahildir
dizi işleme için.
6.5.4 Dizi Başlatma
Bazı diller, dizileri depolandıkları sırada başlatmak için araçlar sağlar.
tahsis edilir. Fortran 95+ sürümünde, bir dizi, ona bir dizi atanarak başlatılabilir.
beyanında toplanır. Tek boyutlu bir dizi için bir dizi toplamı
parantez ve eğik çizgilerle ayrılmış değişmezlerin listesi. Örneğin, biz olabilir
Tamsayı, Boyut (3) :: Liste = (/0, 5, 5/)
C, C++, Java ve C# da dizilerinin başlatılmasına izin verir, ancak bir
yeni bükülme: C deklarasyonunda
int listesi [] = {4, 5, 7, 83};
5. Alt simge aralığı 1000 olabilir. . 1009.

Sayfa 286
6.5 Dizi Tipleri 265
derleyici dizinin uzunluğunu ayarlar. Bu kolaylık sağlamak içindir
ama maliyetsiz değildir. Sistemin olma olasılığını etkin bir şekilde ortadan kaldırır.
yanlışlıkla bırakmak gibi bazı programcı hatalarını algılayabilir.
değer listeden çıkar.
Bölüm 6.3.2'de tartışıldığı gibi, C ve C++'daki karakter dizileri
char dizileri olarak belirtilir . Bu diziler, dize sabitlerine başlatılabilir,
de olduğu gibi
karakter adı [] = "freddie";
Tüm dizeler sonlandırıldığından, dizi adı sekiz öğeye sahip olacaktır.
için sistem tarafından dolaylı olarak sağlanan boş bir karakterle (sıfır)
dizi sabitleri.
C ve C++'daki dize dizileri de dize değişmezleri ile başlatılabilir. İçinde
bu durumda dizi, karakterlerin işaretçilerinden biridir. Örneğin,
char *isimler [] = {"Bob", "Jake", "Darcie"};
Bu örnek, C ve C++'daki karakter değişmezlerinin doğasını gösterir. İçinde
char dizisini başlatmak için kullanılan bir dize değişmezinin önceki örneği
name , değişmez değer bir char dizisi olarak alınır . Ancak son örnekte ( isimler ),
değişmezler karakterlerin işaretçileri olarak alınır, bu nedenle dizi bir dizidir
karakterlere işaretçiler. Örneğin, isimler[0] 'B' harfinin bir göstergesidir.
'B' , 'o' , ' b' karakterlerini içeren değişmez karakter dizisinde ve
boş karakter.
Java'da, bir dizi referansı tanımlamak ve başlatmak için benzer sözdizimi kullanılır.
için dize nesneleri. Örneğin,
String[] isimler = ["Bob", "Jake", "Darcie"];
Ada, bildirimde dizileri başlatmak için iki mekanizma sağlar
beyan: saklanacakları sıraya göre listeleyerek veya
=> operatörünü kullanarak bunları doğrudan bir dizin konumuna atamak ;
Ada'ya ok denir . Örneğin, aşağıdakileri göz önünde bulundurun:
Listesi: dizi (1..5) arasında bir tamsayı: = (1, 3, 5, 7, 9);
Demet: dizi (1..5) arasında bir tamsayı: = (=> 17 1, => 34 3,
diğerleri => 0);
İlk ifadede, List dizisinin tüm elemanları başlangıç ​​değerlerine sahiptir,
dizi öğesi konumlarına bulundukları sıraya göre atanan
belli olmak. İkincisinde, birinci ve üçüncü dizi elemanları kullanılarak başlatılır.
doğrudan atama ve diğerleri yan tümcesi kalanları başlatmak için kullanılır.
elementler. Fortran'da olduğu gibi, bu parantez içindeki değer listelerine toplu denir.
kapı değerleri .

Sayfa 287
266
Bölüm 6 Veri Tipleri
6.5.5 Dizi İşlemleri
Bir dizi işlemi, bir dizi üzerinde birim olarak çalışan bir işlemdir. en kom-
mon dizi işlemleri atama, sıralama, eşitlik için karşılaştırma ve
Bölüm 6.5.5'te ayrı ayrı tartışılan eşitsizlik ve dilimler.
C tabanlı diller, aşağıdakiler dışında herhangi bir dizi işlemi sağlamaz.
Java, C++ ve C# yöntemleriyle. Perl dizi atamalarını destekler
ancak karşılaştırmaları desteklemez.
Ada, sağ taraftakiler de dahil olmak üzere dizi atamalarına izin verir.
dizi adı yerine toplu bir değer. Ada ayrıca katener sağlar,
ve işareti ( & ) ile belirtilir. Katenasyon iki tek- arasında tanımlanır.
boyutlu diziler ve tek boyutlu bir dizi ile bir skaler arasında.
Ada'daki neredeyse tüm türler, eşitlik için yerleşik ilişkisel operatörlere sahiptir ve
eşitsizlik.
Python'un dizileri, tüm özelliklere sahip olmalarına rağmen listeler olarak adlandırılır.
dinamik diziler. Nesneler herhangi bir türden olabileceğinden, bu diziler
heterojen. Python, yalnızca bir referans olmasına rağmen dizi ataması sağlar.
değişiklik. Python ayrıca dizi dizileme ( + ) ve eleman için işlemlere sahiptir.
üyelik ( içinde ). İki farklı karşılaştırma operatörü içerir: biri
iki değişkenin aynı nesneye ( is ) başvurup göndermediğini ve bir
ne olursa olsun, başvurulan nesnelerdeki tüm karşılık gelen nesneleri karşılaştıran
eşitlik için ( == ).
Python gibi, Ruby'nin dizilerinin öğeleri de nesnelere referanslardır. Ve
Python gibi, iki dizi arasında bir == operatörü kullanıldığında sonuç doğrudur
yalnızca iki dizinin uzunluğu aynıysa ve karşılık gelen öğeler
eşit. Ruby'nin dizileri, bir Array yöntemiyle sıralanabilir .
Fortran 95 + olarak adlandırılan dizi işlemleri de içerir elemen-
tal çünkü bunlar dizi öğesi çiftleri arasındaki işlemlerdir. Örneğin,
iki dizi arasındaki ekleme operatörü ( + ), aşağıdakilerin toplamlarının bir dizisini verir.
iki dizinin eleman çiftleri. Atama, aritmetik, ilişkisel ve
mantıksal operatörlerin tümü, herhangi bir boyut veya şekildeki diziler için aşırı yüklenmiştir. 95+
ayrıca matris çarpımı, matris için içsel veya kitaplık işlevleri içerir
devrik ve vektör nokta çarpımı.
F#, Array modülünde birçok dizi operatörü içerir . Bunlar arasında
Array.append , Array.copy ve Array.length .
Diziler ve işlemleri APL'nin kalbidir; en güçlüsüdür
şimdiye kadar geliştirilmiş dizi işleme dili. Göreceli belirsizliği ve belirsizliği nedeniyle
sonraki diller üzerinde etkisinin olmaması, ancak burada sadece bir bakış sunuyoruz
dizi işlemlerine girer.
APL'de vektörler için dört temel aritmetik işlem tanımlanmıştır.
(tek boyutlu diziler) ve matrisler ile skaler işlenenler. İçin
örnek,
A + B
Geçerli bir ifade, ister olan bir ve B olan sayısal değişkenler, vektörler veya
matrisler.

Sayfa 288
6.5 Dizi Türleri 267
APL, vektörler ve matrisler için birli operatörler koleksiyonu içerir.
bazıları aşağıdaki gibidir (burada V bir vektördür ve M bir matristir):
V, V'nin öğelerini tersine çevirir
M, M'nin sütunlarını tersine çevirir
M, M satırlarını tersine çevirir
O \ M aktarır M (kendi sıraları tersi sütunları ve tersi olur)
÷ M tersine döndüğü E
APL ayrıca, diğer operatörleri olarak kabul eden birkaç özel operatör içerir.
işlenenler. Bunlardan biri ile belirtilen iç çarpım operatörüdür.
bir dönem ( . ). İkili operatörler olan iki işlenen alır. Örneğin,
+.×
vektörler veya matrisler olmak üzere iki bağımsız değişken alan yeni bir operatördür. ilk o
iki bağımsız değişkenin karşılık gelen öğelerini çarpar ve ardından
Sonuçlar. Örneğin, A ve B vektörlerse,
A × B
A ve B'nin matematiksel iç çarpımıdır (
A ve B'nin karşılık gelen elemanları ). İfade
A +.× B
A ve B'nin iç çarpımının toplamıdır . Eğer A ve B matrisleri vardır bu ifadelere
sion, A ve B'nin matris çarpımını belirtir .
APL'nin özel operatörleri aslında fonksiyonel formlardır.
Bölüm 15'te açıklanmıştır.
6.5.6 Dikdörtgen ve Pürüzlü Diziler
Bir dikdörtgen dizi tüm satırları sahip olan bir multidimensioned dizidir
aynı sayıda eleman ve tüm sütunlar aynı sayıda
elementler. Dikdörtgen diziler, dikdörtgen tabloları tam olarak modeller.
Bir dişli dizisi olan satırların uzunlukları olması gerekli değildir biridir
aynı. Örneğin, pürüzlü bir matris, biri 5 elemanlı üç satırdan oluşabilir.
biri 7 elemanlı, diğeri 12 elemanlı. Bu aynı zamanda
sütunlar ve daha yüksek boyutlar. Yani, eğer üçüncü bir boyut (katmanlar) varsa, her biri
katman farklı sayıda elemana sahip olabilir. Pürüzlü diziler mümkün hale getirildi
çok boyutlu diziler aslında dizi dizileri olduğunda. Örneğin, bir
matrix, tek boyutlu dizilerden oluşan bir dizi olarak görünür.
C, C++ ve Java pürüzlü dizileri destekler ancak dikdörtgen dizileri desteklemez. Bunun içinde
dillerde, çok boyutlu bir dizinin bir öğesine yapılan bir başvuru, ayrı bir
her boyut için parantez çiftini değerlendirin. Örneğin,
myArray[3][7]

Sayfa 289
268
Bölüm 6 Veri Tipleri
Fortran, Ada, C# ve F# dikdörtgen dizileri destekler. (C# ve F# da destekler
pürüzlü diziler.) Bu durumlarda, öğelere yapılan referanslardaki tüm alt simge ifadeleri
tek bir çift parantez içine yerleştirilir. Örneğin,
benimArray[3, 7]
6.5.7 Dilimler
Bir dizinin bir dilimi , o dizinin bir alt yapısıdır. Örneğin, eğer A bir
matris, o zaman A'nın ilk satırı , son satır ve
ilk sütun. Bir dilimin yeni bir veri türü olmadığını anlamak önemlidir. Yerine,
bir dizinin parçasına bir birim olarak başvurmak için bir mekanizmadır. diziler olamazsa
Bir dilde birimler olarak manipüle edildiğinde, bu dilin dilimler için bir kullanımı yoktur.
Aşağıdaki Python bildirimlerini göz önünde bulundurun:
vektör = [2, 4, 6, 8, 10, 12, 14, 16]
mat = [[1, 2, 3],[4, 5, 6],[7, 8, 9]]
Python dizileri için varsayılan alt sınırın 0 olduğunu hatırlayın.
Python dilim başvurusu, iki nokta üst üste ile ayrılmış bir çift sayısal ifadedir. bu
birincisi, dilimin ilk abonesidir; ikincisi, sondan sonraki ilk alt simgedir
dilimdeki alt simge. Bu nedenle vektör[3:6] , üç elemanlı bir dizidir.
vektörün dördüncü ila altıncı öğeleri ( 3 alt simgeli öğeler ,
4 ve 5 ). Bir matris satırı, yalnızca bir alt simge verilerek belirtilir. Örneğin,
mat [1] ikinci sıraya atıfta mat ; satırın bir kısmı ile belirtilebilir
tek boyutlu bir dizinin parçası olarak aynı sözdizimi. Örneğin, mat[0][0:2]
[1, 2] olan ilk mat sırasının birinci ve ikinci elemanına atıfta bulunur .
Python ayrıca daha karmaşık dizi dilimlerini de destekler. Örneğin, vec-
tor[0:7:2] vektörün diğer tüm öğelerine başvurur , ancak bunlar dahil değildir:
alt simge ile başlanarak, alt simge 7 ile elemanının ing 0 olduğu,
[2, 6, 10, 14] .
Perl, iki formun dilimlerini, belirli bir abonelik listesini veya bir dizi
abonelikler. Örneğin,
@list[1..5] = @list2[3, 5, 7, 9, 13];
Dilim referanslarının skaler adları değil dizi adlarını kullandığına dikkat edin, çünkü dilimler
dizilerdir (skaler değil).
Ruby, dilimleri Array nesnesinin dilim yöntemiyle destekler ;
üç tür parametre alabilir. Tek bir tamsayı ifade parametresi
bir alt simge olarak yorumlanır, bu durumda dilim öğeyi
verilen alt simge. Eğer dilim iki tamsayı ifade parametrelerini verilir, ilk
başlangıç ​​indisi olarak yorumlanır ve ikincisi sayı olarak yorumlanır.
dilimdeki öğelerin ber'i. Örneğin, listenin aşağıdaki gibi tanımlandığını varsayalım :
liste = [2, 4, 6, 8, 10]

Sayfa 290
6.5 Dizi Türleri 269
list.slice(2, 2) [6, 8] değerini döndürür . Üçüncü parametre şekilde dilim olan
bir tamsayı ifadesi, iki nokta ve bir saniye şeklinde bir aralık
tamsayı ifadesi. Bir aralık parametresiyle, dilim , elektriğin bir dizisini döndürür.
verilen alt indis aralığı ile ment. Örneğin, list.slice (1.3)
[4, 6, 8] döndürür .
6.5.8 Değerlendirme
Diziler hemen hemen tüm programlama dillerine dahil edilmiştir. Pri-
Mary, Fortran'a girişlerinden bu yana ilerlemeler ben dahil oldum
olası alt simge türleri, dilimler ve tabii ki dinamik olarak tüm sıralı türlerin
diziler. Bölüm 6.6'da tartışıldığı gibi, dizilerdeki en son gelişmeler,
ilişkisel diziler.
6.5.9 Dizi Türlerinin Uygulanması
Dizileri uygulamak, derleme süresinden çok daha fazla çaba gerektirir
ilkel türlerin uygulanması. Dizi öğelerine erişime izin veren kod
derleme zamanında oluşturulmalıdır. Çalışma zamanında, bu kod çalıştırılmalıdır.
eleman adresleri üretir. Adresi önceden hesaplamanın bir yolu yok
gibi bir referansla erişildi
liste[k]
Tek boyutlu bir dizi, bitişik belleğin bir listesi olarak uygulanır.
hücreler. Dizi listesinin bir alt simge aralığı alt sınırına sahip olarak tanımlandığını varsayalım.
ve 0 . Liste için erişim işlevi genellikle şu şekildedir:
address( list[k] ) = address( list[0] ) + k * element_size
burada toplamanın ilk işleneni erişim fonksiyonunun sabit kısmıdır.
tion ve ikincisi değişken kısımdır.
Öğe türü statik olarak bağlıysa ve dizi statik olarak bağlıysa
depolama, daha sonra sabit parçanın değeri çalışma zamanından önce hesaplanabilir.
Ancak toplama ve çarpma işlemleri çalışma zamanında yapılmalıdır.
Bu erişim fonksiyonunun keyfi bir alt sınır için genelleştirilmesi şu şekildedir:
adres( liste[k] ) = adres( liste [alt_sınır]) +
(( k - alt_sınır) * eleman_boyutu)
Tek boyutlu diziler için derleme zamanı tanımlayıcısı aşağıdakilere sahip olabilir:
Şekil 6.4'te gösterilen form. Tanımlayıcı, aşağıdakiler için gerekli bilgileri içerir:
erişim işlevini oluşturun. Dizin aralıklarının çalışma zamanı denetimi yapılmadıysa
ve özniteliklerin tümü statiktir, bu durumda yalnızca erişim işlevi gereklidir.
yürütme; tanımlayıcıya gerek yoktur. Dizin aralıklarının çalışma zamanı denetimi ise
yapıldıysa, bu dizin aralıklarının bir çalışma zamanı tanımlayıcısında saklanması gerekebilir. Eğer
belirli bir dizi türünün alt simge aralıkları statiktir, o zaman aralıklar

Sayfa 291
270
Bölüm 6 Veri Tipleri
kontrolü yapan koda dahil edilmiştir, böylece gerekliliği ortadan kaldırır.
çalışma zamanı tanımlayıcısı. Tanımlayıcı girişlerinden herhangi biri dinamik olarak bağlıysa,
daha sonra tanımlayıcının bu bölümleri çalışma zamanında korunmalıdır.
Gerçek çok boyutlu diziler, yani dizi dizileri olmayanlar,
uygulanması tek boyutlu dizilerden daha karmaşıktır, ancak
daha fazla boyuta genişletmek basittir. Donanım belleği doğrusaldır—
genellikle basit bir bayt dizisidir. Yani iki tane olan veri türlerinin değerleri
veya daha fazla boyut, tek boyutlu belleğe eşlenmelidir.
Çok boyutlu dizilerin tek bir diziye eşlenmesinin iki yolu vardır.
boyut: satır ana düzeni ve sütun ana düzeni. Gelen satır majör sırayla ,
ilk alt indisleri alt sınır değerine sahip dizinin elemanları
bu alt simge önce depolanır, ardından ikinci değerinin öğeleri gelir.
ilk alt simge, vb. Dizi bir matris ise, satırlar halinde saklanır. İçin
örneğin, matrisin değerleri varsa
3 4 7
6 2 5
1 3 8
olarak satır ana sırayla saklanır
3, 4, 7, 6, 2, 5, 1, 3, 8
Gelen kolon büyük amacıyla , bir dizinin elemanları, son alt olarak var
komut dosyası, bu alt simgenin alt sınır değeri önce saklanır, ardından
son alt simgenin ikinci değerinin öğeleri vb. dizi ise
bir matris, sütunlar tarafından saklanır. Örnek matris sütunda saklanmışsa
büyük sipariş, bellekte aşağıdaki sıraya sahip olacaktır:
3, 6, 1, 4, 2, 3, 7, 5, 8
Sütun ana sırası Fortran'da kullanılır, ancak doğru olan diğer diller
çok boyutlu diziler satır ana düzenini kullanır.
Çok boyutlu bir dizi için erişim işlevi, dizinin eşlenmesidir.
temel adres ve öğenin belleğindeki adrese bir dizi dizin değeri
indeks değerleri ile belirlenir. İki boyutlu diziler için erişim işlevi
Satırda saklanan ana sıra aşağıdaki gibi geliştirilebilir. Genel olarak, adres
Şekil 6.4
Derleme zamanı tanımlayıcısı
tek boyutlu için
diziler
eleman tipi
Sıralamak
dizin türü
Dizin alt sınırı
Dizin üst sınırı
Adres

Sayfa 292
bir elemanın, yapının temel adresi artı eleman boyutu süreleridir.
Yapıda kendisinden önce gelen öğelerin sayısı. Satırdaki bir matris için
ana düzen, bir öğeden önce gelen öğelerin sayısı sayıdır
elemanın üzerindeki satır sayısı çarpı bir satırın boyutu artı eleman sayısı
elemanın solunda. Bu, varsaydığımız Şekil 6.5'te gösterilmektedir.
bu alt simge alt sınırlarının tümü sıfırdır.
Gerçek bir adres değeri elde etmek için, adresten önce gelen eleman sayısı
istenen eleman, eleman boyutu ile çarpılmalıdır. Şimdi, erişim işlevi-
olarak yazılabilir
konum( a[i,j] ) = a[0, 0] adresi
+ ((((Yukarıdaki satır sayısı i inci bir satırın) * (boyut))
+ (Elemanların sayısı sol j inci ) kolon) *
eleman boyutu)
Yukarıdaki satır sayısı nedeniyle i inci satır olan I ve elemanların sayısı
sol için j inci sütundur j elimizdeki,
konum( a[i, j] ) = a[0, 0] adresi + ((( i * n ) + j ) *
element_size)
burada n , satır başına eleman sayısıdır. İlk terim sabit kısımdır
ve sonuncusu değişken kısımdır.
İsteğe bağlı alt sınırlara genelleme, aşağıdaki erişimle sonuçlanır
işlev:
konum( a[i, j] ) = a[row_lb, col_lb]'nin adresi
+ ((( i - satır_lb) * n) + ( j - sütun_lb)) * eleman_boyutu
burada row_lb satırların alt sınırıdır ve col_lb satırların alt sınırıdır.
kolonlar. Bu forma yeniden düzenlenebilir
Şekil 6.5
konumu
a'daki [i,j] öğesi
matris
6.5 Dizi Türleri 271

Sayfa 293
272
Bölüm 6 Veri Tipleri
konum( a[i, j] ) = bir [row_lb, col_lb] adresi
- (((row_lb * n) + col_lb) * element_size)
+ ((( i * n ) + j ) * element_size)
burada ilk iki terim sabit kısım ve son terim değişken kısımdır.
Bu, keyfi sayıda boyuta nispeten kolayca genelleştirilebilir.
Bir dizinin her boyutu için bir toplama ve bir çarpma komutu
erişim işlevi için gereklidir. Bu nedenle, dizilerin öğelerine erişim
birkaç abonelik maliyetlidir. Bir çok boyutlu için derleme zamanı tanımlayıcısı
sional dizi Şekil 6.6'da gösterilmiştir.
Şekil 6.6
Derleme zamanı
bir için tanımlayıcı
çok boyutlu dizi
0
6.6 İlişkili Diziler
Bir ilişkisel dizi , sıralanmamış bir veri öğeleri koleksiyonudur.
anahtar adı verilen eşit sayıda değerle indekslenir . İlişkisel olmayan durumda
diziler, dizinlerin hiçbir zaman saklanması gerekmez (düzenlilikleri nedeniyle). içinde
ilişkisel dizi, ancak kullanıcı tanımlı anahtarlar yapıda saklanmalıdır.
Dolayısıyla bir ilişkisel dizinin her elemanı aslında bir çift varlık, bir anahtar ve bir
değer. Bu veri yapısını göstermek için Perl'in ilişkisel diziler tasarımını kullanıyoruz.
İlişkili diziler ayrıca doğrudan Python, Ruby ve Lua tarafından desteklenir.
Java, C++, C# ve F# standart sınıf kitaplıkları.
İlişkisel dizilere özgü tek tasarım sorunu,
unsurlarına atıfta bulunur.
6.6.1 Yapı ve İşlemler
Perl'de, ilişkisel dizilere karma denir , çünkü uygulamada
öğeleri, hash işlevleriyle depolanır ve alınır. ad alanı
Perl karmaları için farklıdır: Her karma değişken adı yüzde ile başlamalıdır
işareti ( % ). Her karma öğe iki bölümden oluşur: bir dize olan bir anahtar ve

Sayfa 294
6.6 İlişkili Diziler 273
skaler olan bir değer (sayı, dize veya başvuru). Hash'ler şu şekilde ayarlanabilir:
atama ifadesi ile değişmez değerler, olduğu gibi
%maaşlar = ("Gary" => 75000, "Perry" => 57000,
"Mary" => 55750, "Cedric" => 47850);
Bireysel öğe değerlerine benzer bir gösterim kullanılarak başvurulur.
Perl dizileri için kullanılan. Anahtar değeri parantez içine alınır ve karma adı
ilk karakter dışında aynı olan bir skaler değişken adı ile değiştirilir.
Hashler skaler olmasa da hash elemanlarının değer kısımları skalerdir, yani
karma öğe değerlerine yapılan başvurular skaler adları kullanır. Bu skaler değişkeni hatırlayın
isimler dolar işaretiyle ( $ ) başlar. Örneğin,
$maaşlar{"Perry"} = 58850;
Aynı atama ifadesi formu kullanılarak yeni bir öğe eklenir. Bir element
olduğu gibi , silme operatörü ile karmadan kaldırılabilir .
$maaşları sil {"Gary"};
Hash'in tamamı, ona aşağıdaki gibi boş değişmez değer atanarak boşaltılabilir.
@maaşlar = ();
Perl karmasının boyutu dinamiktir: Bir eleman eklendiğinde büyür ve
bir eleman silindiğinde ve ayrıca atama ile boşaltıldığında küçülür
boş kelimenin tam anlamıyla. Mevcut bağlı olarak doğru veya yanlış operatör döner
işlenen anahtarının hash içindeki bir öğe olup olmadığı. Örneğin,
if (varsa $maaşlar{"Shelly"}) . . .
Anahtarlar operatörü bir karma uygulandığında, anahtarların, bir dizi döner
karma. Değerleri operatör karma değerleri için aynısını yapar. bu
her operatör, bir karmanın eleman çiftleri üzerinde yinelenir.
Python'un sözlükler olarak adlandırılan ilişkisel dizileri benzerdir.
değerlerin tümü nesnelere referanslar olması dışında, Perl'inkilerle aynıdır. dernek-
Ruby tarafından desteklenen diziler Python'unkilere benzer, ancak bunun dışında
anahtarlar, yalnızca dizeler yerine herhangi bir nesne 6 olabilir . ilerleme var
anahtarların dizge olması gereken Perl'in karmalarından PHP'nin dizilerine,
anahtarların tamsayılar veya dizeler olabileceği, Ruby'nin karmalarına göre, herhangi bir
type nesnesi bir anahtar olabilir.
PHP'nin dizileri hem normal diziler hem de ilişkisel dizilerdir. Onlar yapabilir
ya olarak tedavi edilir. Dil, hem dizinlenmiş hem de
6. Değişen nesneler iyi anahtarlar oluşturmaz çünkü değişiklikler hash değerini değiştirebilir
fonksiyon değeri. Bu nedenle, diziler ve karmalar asla anahtar olarak kullanılmaz.

Sayfa 295
röportaj yapmak
Lua
ROBERTO IERUSALIMSCHY
Roberto Ierusalimschy, Lua betik dilinin yaratıcılarından biridir.
oyun geliştirme ve gömülü sistem uygulamalarında yaygın olarak kullanılmaktadır. O bir
Pontificia Üniversitesi Bilgisayar Bilimleri Bölümü'nde doçent
dade Católica Brezilya'da Rio de Janeiro yapmak. (Lua hakkında daha fazla bilgi için
www.lua.org.)
İlk olarak nasıl ve nerede tanıştınız?
bilgi işlem? 1978'de üniversiteye girmeden önce hiçbir şeyim yoktu.
bilgisayar hakkında fikir. okumaya çalıştığımı hatırlıyorum
Fortran'da programlama üzerine bir kitap ama
değişkenler ve sabitler için tanımların ilk bölümü.
Üniversitedeki ilk yılımda bir Programlama aldım
Fortran'da 101 kurs. O zaman pro-
IBM 370 ana bilgisayarında gramlama atamaları. Biz
kodumuzla kartları delmek zorunda kaldı, güverteyi kuşattı
bazı sabit JCL kartlarıyla ve bir operatöre verin.
Bir süre sonra (genellikle birkaç saat) bir listemiz var.
Sıklıkla yalnızca derleyici hataları olan sonuçlar.
Kısa bir süre sonra bir arkadaşım getirdi
yurtdışında bir mikro bilgisayar, 4K baytlık bir Z80 CPU
hafıza. Bunun için her türlü programı yapmaya başladık.
makine, hepsi montajda - veya daha doğrusu makinede
bir montajcısı olmadığı için kod. bizim yazdık
derlemedeki programlar, daha sonra bunları elle çevrildi
Onları onaltılık belleğe girmek için çalıştırın.
O zamandan beri aşığım.
Birkaç başarılı programlama olmuştur
akademik ortamlarda tasarlanan diller
son 25 yıl. Akademisyen olmanıza rağmen,
Lua, çok pratik uygulamalar için tasarlanmıştır.
Lua'yı akademik veya endüstriyel olarak görüyor musunuz?
dilim? Lua kesinlikle endüstriyel bir dildir,
ama akademik bir "aksan" ile. Lua için yaratıldı
iki endüstriyel uygulamada kullanılmıştır ve
endüstriyel uygulamalar tüm ömrü boyunca. çok olmaya çalıştık
tasarımında pragmatik. Ancak ilki hariç
versiyonunda, hiçbir zaman tipik bir baskı altında olmadık.
endüstriyel bir ortam. Her zaman lüksümüz vardı
yeni bir sürümün ne zaman yayınlanacağını veya
Kullanıcı taleplerinin kabul edilip edilmeyeceği. Bu bize biraz verdi
diğer dillerin hoşlanmadığı enlem.
Daha yakın zamanlarda, bazı akademik çalışmalar yaptık.
Lua ile araştırma. Ama birleşmek uzun bir süreç
bu akademik sonuçlar resmi dağıtıma;
çoğu zaman bu sonuçların çok az doğrudan
Lua'ya etkisi. Yine de güzel şeyler oldu
kayıt tabanlı sanal makine gibi istisnalar
ve "geçici tablolar" (Lua 5.2'de görünecek).
Lua'nın büyüdüğünü söyledin.
tasarlanmış. Ne demek istediğini yorumlayabilir misin
ve bunun faydalarının ne olduğunu düşünüyorsunuz
yaklaşmak? en önemli parçaları demek istedik
Lua ilk versiyonunda mevcut değildi. Dil
çok küçük ve basit bir dil olarak başladı ve
evrimleştikçe ilgili özelliklerinden birkaçı.
Faydaları (ve çekilişi) hakkında konuşmadan önce
arkalarında) bu yaklaşımın, açıklığa kavuşturmama izin verin
bu yaklaşımı seçmedi. Hiç düşünmedik, “bırak
yeni bir dil yetiştiriyoruz.” Henüz oldu.
Tasarım yaparken en zor kısım bu sanırım
dil, farklı mekanizmaların nasıl olacağını öngörmektir.
günlük kullanımda etkileşim. Bir dili yükselterek—yani,
parça parça oluşturarak - bunların çoğundan kaçınabilirsiniz.
etkileşim sorunları, her yeni hakkında düşünebileceğiniz gibi
özellik yalnızca dilin geri kalanı yerinde olduktan sonra
ve gerçek uygulamalarda gerçek kullanıcılar tarafından test edilmiştir.
Tabii ki, bu yaklaşımın da büyük bir dezavantajı var:
En çok ihtiyaç duyulan yeni bir özelliğin ortaya çıktığı bir noktaya gelebilirsiniz.
Halihazırda sahip olduklarınızla bağdaşmaz.
Lua, kurulduğu günden bu yana çeşitli şekillerde değişti.
ilk olarak 1994 yılında piyasaya çıktı. Orada olduğunu söylediniz.
dahil etmediğin için pişman olduğun zamanlar oldu
Lua'da bir Boole türü. neden basitçe eklemedin
bir? Bu kulağa komik gelebilir, ama gerçekten özlediğimiz şey
"yanlış" değeriydi; "doğru" bir değer için hiçbir işimiz yoktu.
274

Sayfa 296
Orijinal LISP gibi, Lua da sıfırı yanlış olarak değerlendirdi.
ve diğer her şey doğru. Sorun şu ki sıfır
ayrıca birimleştirilmiş bir değişkeni temsil eder. yoktu
birimselleştirilmiş bir değişken arasında ayrım yapmanın yolu
yanlış bir değişken. Yani, yapmak için yanlış bir değere ihtiyacımız vardı.
bu ayrım mümkün. Ama gerçek değer kullanımdı.
az; 1 veya başka bir sabit yeterince iyiydi.
Sanırım bu, bizim “endüstri-
deneme" zihnimiz ile "akademik" zihnimiz çatıştı. A
gerçekten pragmatik zihin Boole türünü eklerdi
iki kere düşünmeden. Ama akademik aklımız
bu görgüsüzlüğe üzüldü. Sonunda pragmatik taraf
kazandı ama biraz zaman aldı.
En önemli Lua özellikleri nelerdi,
önişlemci dışında, daha sonra
hatalı özellikler olarak kabul edildi ve kaldırıldı
dil? Diğer büyük yanlışları hatırlamıyorum.
türler. Lua'dan birkaç özelliği kaldırdık, ancak
çoğunlukla yerlerini yenileri aldıkları için, genellikle
Bir anlamda “daha ​​iyi” özellik. Bu etiketle oldu
yöntemler (yerini metametotlar alır), zayıf referans
C API'sindeki (zayıf tablolar tarafından değiştirilen) ve
upvalues ​​(uygun sözcüksel kapsam belirleme ile değiştirilir).
Lua için bozulacak yeni bir özellik ne zaman
geriye dönük uyumluluk düşünülürse bu nasıl olur
karar verildi? Bunlar her zaman zor kararlardır.
İlk olarak, önleyebilecek başka bir format bulmaya çalışıyoruz.
veya en azından uyumsuzluğu azaltın. bu değilse
mümkünse, gelirin etrafında kolay yollar sağlamaya çalışıyoruz.
uygunluk. (Örneğin, bir işlevi kaldırırsak
ayrı bir uygulama sağlayabileceğimiz çekirdek kitaplık
programcının ona dahil edebileceği
kod.) Ayrıca, bunun ne kadar zor olacağını da ölçmeye çalışıyoruz.
uyumsuzluğu tespit edin ve düzeltin. Eğer yeni özellik-
ture sözdizimi hataları oluşturur (örneğin, yeni bir ayrılmış sözcük),
bu o kadar da kötü değil; hatta bir otomatik sağlayabiliriz
eski kodu düzeltmek için araç. Ancak, eğer yeni özellik
ince hatalar üretir (örneğin, önceden var olan bir işlev dönüşü-
farklı bir sonuç), bunu kabul edilemez buluyoruz.
Ruby'ninki gibi yineleyici yöntemler,
for ifadesi yerine Lua'yı tercih etti
bu eklendi? Hangi düşünceler yol açtı
tercih? Sadece dikkate alınmadılar, aynı zamanda
fiilen uygulandı! 3.1 sürümünden beri (1998'den itibaren),
Lua bir işlev olmuştur “foreach” , yani geçerli bir
bir tablodaki tüm çiftlere verilen fonksiyon. Benzer şekilde,
"gsub" her birine belirli bir işlevi uygulamak kolaydır
bir dizedeki karakter.
için özel bir “blok” mekanizması yerine
yineleyici gövdesi, Lua için birinci sınıf işlevleri kullandı
görev. Bir sonraki örneğe bakın:
—'', isimlerden değerlere bir tablodur
— sonraki "döngü" ile tüm tuşları yazdırır
10'dan büyük değerler
foreach(t, fonksiyon(anahtar, değer)
değer > 10 ise print(key) end
son)
Ancak, yineleyicileri ilk uyguladığımızda, işlev-
Lua'daki metinler tam bir sözcüksel kapsam belirlemeye sahip değildi. Dahası,
sözdizimi biraz ağırdır (makrolar yardımcı olacaktır). Ayrıca,
çıkış ifadeleri (break ve return) her zaman kafa karıştırıcıdır.
yineleme gövdelerinde kullanıldığında. Yani, sonunda biz
for ifadesi için karar verdi .
Ancak “gerçek yineleyiciler” Lua'da hala kullanışlı bir tasarımdır.
artık işlevlerin uygun sözcüksel kapsamı olduğuna göre,
ing. Lua kitabımda, aşağıdakilerle ilgili bölümü bitiriyorum :
gerçek yineleyicilerin tartışıldığı ifade.
ne zaman kastettiğini kısaca anlatırmısın
Lua'yı genişletilebilir bir uzantı lan-
guaj? “Genişletilebilir bir dil” çünkü
diğerlerinde tanımlanan yeni işlevleri ve türleri kaydetmesi kolay
Diller. Bu yüzden dili genişletmek kolaydır. bir
daha somut bir bakış açısıyla, Lua'dan C'yi aramak kolaydır.
Bir “uzantı dili”dir, çünkü kullanımı kolaydır.
bir uygulamayı genişletmek için Lua'yı kullanın,
uygulama için bir makro dili. (Bu, "senaryo-
ing” daha saf anlamında.) Daha somut bir noktadan
Lua'yı C'den aramak kolaydır.
Veri yapıları dizilerden, kayıtlardan,
ve bunların kombinasyonlarına hash'ler. Yapabilir misin
Lua'nın tablolarının önemini tahmin edin
programlamada veri yapılarının evrimi
Diller? Lua masasında herhangi bir şey olduğunu sanmıyorum.
diğer dillerin evriminde önemi. Belki
gelecekte değişecek ama emin değilim
o. Benim görüşüme göre, Lua tablolarının sunduğu ana fayda
basitliği, "hepsi bir arada" bir çözümdür. Ama bu sim-
katılığın maliyetleri vardır: Örneğin,
Lua programları, kısmen tablolar nedeniyle çok zor
çok genel ve her yerde var olmak. Her dilin kendine ait
kendi öncelikleri.
275

Sayfa 297
276
Bölüm 6 Veri Tipleri
öğelere karma erişim. Bir dizi, ile oluşturulan öğelere sahip olabilir
dize karma anahtarlarıyla oluşturulan basit sayısal dizinler ve öğeler.
Lua'da tablo türü tek veri yapısıdır. Bir Lua tablosu bir ilişki-
hem anahtarların hem de değerlerin herhangi bir türde olabileceği bir dizi. bir tablo olabilir
geleneksel dizi, ilişkisel dizi veya kayıt (yapı) olarak kullanılır. Kullanıldığında
geleneksel bir dizi veya ilişkisel bir dizi olarak, tuşların etrafında parantezler kullanılır.
Kayıt olarak kullanıldığında, anahtarlar alan adlarıdır ve alanlara yapılan referanslar,
Nokta gösterimini (record_name kullanın . alan_adı).
Lua'nın ilişkisel dizilerinin kayıt olarak kullanımı Bölüm 6.7'de tartışılmaktadır.
C# ve F#, bir .NET sınıfı aracılığıyla ilişkisel dizileri destekler.
Öğelerin aranması durumunda, ilişkisel bir dizi bir diziden çok daha iyidir.
gereklidir, çünkü öğelere erişmek için kullanılan örtük karma işlemi
çok verimlidir. Ayrıca, ilişkisel diziler, veri oluşturulacağı zaman idealdir.
saklanan, çalışan adları ve maaşları gibi eşleştirilir. Diğer taraftan,
bir listenin her elemanının işlenmesi gerekiyorsa, bir dizi kullanmak daha verimlidir.
6.6.2 İlişkili Dizileri Uygulamak
Perl'in ilişkisel dizilerinin uygulanması, hızlı aramalar için optimize edilmiştir,
ancak aynı zamanda dizi büyümesi gerektirdiğinde nispeten hızlı yeniden düzenleme sağlar.
o. Her giriş için 32 bitlik bir hash değeri hesaplanır ve girişle birlikte saklanır,
ilişkisel bir dizi başlangıçta karma değerinin yalnızca küçük bir bölümünü kullanır.
Bir ilişkisel dizinin başlangıç ​​boyutunun ötesine genişletilmesi gerektiğinde, karma
işlevin değiştirilmesi gerekmez; bunun yerine, karma değerinin daha fazla biti kullanılır.
Bu olduğunda girişlerin yalnızca yarısı taşınmalıdır. Yani, genişlese de
bir ilişkisel dizinin sion ücretsiz değildir, beklendiği kadar maliyetli değildir.
PHP'nin dizilerindeki öğeler, bir karma işlevi aracılığıyla belleğe yerleştirilir.
tion. Bununla birlikte, tüm öğeler, bulundukları sırayla birbirine bağlanır.
yaratıldı. Bağlantılar, öğelere yinelemeli erişimi desteklemek için kullanılır.
mevcut ve sonraki fonksiyonlar.
6.7 Kayıt Türleri
Bir kayıt veri elemanlarının bir toplama olduğu tek tek elemanlar
isimlerle tanımlanır ve başlangıcından itibaren ofsetler aracılığıyla erişilir.
yapı.
Programlarda genellikle bir veri koleksiyonunu modellemek için bir ihtiyaç vardır.
bireysel öğelerin aynı türde veya boyutta olmadığı. Örneğin,
bir üniversite öğrencisi hakkındaki bilgiler isim, öğrenci numarası,
not ortalaması vb. Böyle bir koleksiyon için bir veri türü şunları kullanabilir:
isim için bir karakter dizisi, öğrenci numarası için bir tam sayı, bir kayan-
not ortalaması için puan vb. Kayıtlar bunun için tasarlanmıştır
tür ihtiyaç.
Kayıtlar ve heterojen diziler aynı görünebilir, ancak bu
durum böyle değil. Heterojen bir dizinin öğelerinin tümü verilere yapılan referanslardır.

Sayfa 298
6.7 Kayıt Türleri 277
genellikle yığın üzerinde, dağınık konumlarda bulunan nesneler. öğeleri bir
kayıt, potansiyel olarak farklı boyutlardadır ve bitişik bellek konumlarında bulunur.
Kayıtlar, en popüler programlama dillerinin tümünün bir parçası olmuştur,
Fortran'ın 90 öncesi sürümleri hariç, 1960'ların başından beri,
COBOL tarafından oluşturulmuştur. Nesne yönelimli programları destekleyen bazı dillerde-
ming, veri sınıfları kayıt görevi görür.
C, C++ ve C#'da kayıtlar yapı veri türüyle desteklenir . İçinde
C++, yapılar, sınıfların küçük bir varyasyonudur. C#'da yapılar da ilişkilidir
sınıflar için değil, aynı zamanda oldukça farklıdır. C# yapıları yığınla ayrılmış değer türleridir,
yığınla ayrılmış başvuru türleri olan sınıf nesnelerinin aksine. yapılar
C++ ve C#'da normalde veri yerine kapsülleme yapıları olarak kullanılır
yapılar. Bunlar, Bölüm 11'de bu kapasitede daha ayrıntılı olarak tartışılmaktadır.
ayrıca ML ve F#'a dahildir.
Python ve Ruby'de kayıtlar, hash'ler olarak uygulanabilir.
selfler dizilerin elemanları olabilir.
Aşağıdaki bölümler, kayıtların nasıl bildirildiğini veya tanımlandığını açıklar,
kayıtlar içindeki alanlara nasıl referanslar yapıldığı ve ortak kayıt
operasyonlar.
Aşağıdaki tasarım sorunları kayıtlara özeldir:
• Alanlara yapılan göndermelerin sözdizimsel biçimi nedir?
• Eliptik referanslara izin veriliyor mu?
6.7.1 Kayıtların Tanımları
Bir kayıt ile bir dizi arasındaki temel fark, kayıt ele-
mentler veya alanlar indeksler tarafından referans alınmaz. Bunun yerine, alanlar adlandırılır
tanımlayıcılarla birlikte verilir ve alanlara referanslar bu tanımlayıcılar kullanılarak yapılır.
Diziler ve kayıtlar arasındaki diğer bir fark, kayıtların bazı lan-
ölçülerin, Bölüm 6.10'da tartışılan sendikaları içermesine izin verilir.
Verilerin bir parçası olan bir kayıt bildiriminin COBOL formu
Bir COBOL programının bölünmesi aşağıdaki örnekte gösterilmiştir:
01 ÇALIŞAN KAYDI.
02 ÇALIŞAN ADI.
05 İLK RESİM X(20).
05 ORTA RESİM X(10).
05 SON RESİM X(20).
02 SAATLİK ORANLI RESİM 99V99.
ÇALIŞAN-KAYIT rekor oluşur ÇALIŞAN-NAME kayıt ve
SAATLİK-ORANI alanı. Rakamları 01 , 02 ve 05 satırlarını başlayacak
kayıt bildirimi, göreceli değerleriyle gösterilen seviye numaralarıdır.
kaydın hiyerarşik yapısı. Bir çizgi ile takip edilen herhangi bir çizgi
daha yüksek seviyeli bir sayının kendisi bir kayıttır. RESİM maddeleri biçimleri göstermek
X(20) 20 alfanümerik karakter belirterek , saha depolama konumlarının
ve 99V99 , ondalık nokta ortada olacak şekilde dört ondalık basamak belirtir .

Sayfa 299
278
Bölüm 6 Veri Tipleri
Ada, kayıtlar için farklı bir sözdizimi kullanır; seviye numaralarını kullanmak yerine
COBOL'un kayıt yapıları basit bir şekilde ortogonal bir şekilde gösterilir.
kayıt bildirimlerini kayıt bildirimlerinin içine yerleştirme. Ada'da kayıtlar olamaz
isimsiz—bunlar tip olarak adlandırılmalıdır. Aşağıdaki Ada beyanını göz önünde bulundurun:
tür Çalışan_Adı_Türü kayıttır
İlk : String (1..20);
Orta : Dize (1..10);
Son : Dize (1..20);
bitiş kaydı;
Çalışan_Record_Type türü kayıttır
Çalışan_Adı: Çalışan_Adı_Type;
Hourly_Rate: Float;
bitiş kaydı;
Çalışan_Kaydı: Çalışan_Kaydı_Type;
Java ve C#'da kayıtlar, iç içe geçmiş kayıtlarla veri sınıfları olarak tanımlanabilir.
iç içe sınıflar olarak tanımlanır. Bu tür sınıfların veri üyeleri, kayıt alanları olarak hizmet eder.
Daha önce belirtildiği gibi, Lua'nın ilişkisel dizileri uygun bir şekilde şu şekilde kullanılabilir:
kayıtlar. Örneğin, aşağıdaki beyanı göz önünde bulundurun:
çalışan.name = "Freddie"
çalışan.hourlyRate = 13.20
Bu atama ifadeleri, çalışan adında bir tablo (kayıt) oluşturur.
name ve hourlyRate adlı iki öğe (alan) başlatıldı.
6.7.2 Kayıt Alanlarına Referanslar
Tek tek kayıt alanlarına yapılan referanslar, sev- ile sözdizimsel olarak belirtilir.
ikisi istenen alanı ve çevresini adlandıran farklı yöntemler
kayıtlar. COBOL alan referansları şu şekildedir:
field_name OF record_name_1 OF . . . OF record_name_n
burada adlandırılan ilk kayıt, aşağıdakileri içeren en küçük veya en içteki kayıttır.
alan. Sıradaki bir sonraki kayıt adı, ilgili kaydın adıdır.
önceki kaydı tutar, vb. Örneğin, ORTA alan
Yukarıdaki COBOL kaydı örneğine şu şekilde başvurulabilir:
ORTA ÇALIŞAN-ÇALIŞAN ADI-KAYIT
Diğer dillerin çoğu, alan referansları için nokta gösterimini kullanır ;
referansın bileşenleri periyotlarla bağlantılıdır. Noktalı isimler
gösterim, COBOL referanslarının tersi sıraya sahiptir: İsmi kullanırlar
en büyük çevreleyen kaydın ilk ve alan adının sonuncusu. Örneğin,
aşağıda, önceki Ada kaydı örneğinde Orta alanına bir referans verilmiştir :
Çalışan_Kaydı.Çalışan_Adı.Orta

Sayfa 300
6.7 Kayıt Türleri 279
C ve C++, aynı sözdizimini kendi üyelerinin referansları için kullanır.
yapılar.
Lua tablosundaki öğelere yapılan başvurular, kaydın sözdiziminde görünebilir.
Bölüm 6.7.1'deki atama ifadelerinde görüldüğü gibi alan referansları. Çok
referanslar ayrıca normal tablo öğeleri biçiminde olabilir; örneğin,
çalışan["isim"] .
Bir kayıt alanına tam nitelikli bir referans , içinde tüm aracıların bulunduğu bir referanstır .
en büyük çevreleyen kayıttan belirli bir alana kadar kayıt adları
referansta isimlendirilmiştir. Hem COBOL hem de Ada örnek alanı,
Yukarıdakiler tam niteliklidir. Tam nitelikli referanslara alternatif olarak,
COBOL, alanları kaydetmek için eliptik referanslara izin verir . Eliptik bir referansta,
alan adlandırılır, ancak ekteki kayıt adlarından herhangi biri veya tümü atlanabilir,
sonuçta ortaya çıkan referans, referans ortamında açık olduğu sürece
ment. Örneğin, İLK , İLK ÇALIŞAN ADI ve İLK
ÇALIŞAN KAYDI , çalışanın şirketteki ilk adına yapılan eliptik referanslardır.
Yukarıda açıklanan COBOL kaydı. Eliptik referanslar bir program olmasına rağmen
Daha fazla kolaylık, ayrıntılı veri yapılarına sahip bir derleyici gerektirirler ve
Başvurulan alanı doğru bir şekilde tanımlamak için prosedürler. Onlar ayrıca
okunabilirlik için biraz zararlı.
6.7.3 Değerlendirme
Kayıtlar, programlama dillerinde sıklıkla değerli veri türleridir. bu
kayıt türlerinin tasarımı basittir ve kullanımları güvenlidir.
Kayıtlar ve diziler yakından ilişkili yapısal biçimlerdir ve bu nedenle
onları karşılaştırmak ilginç. Diziler, tüm veri değerlerine sahip olduğunda kullanılır.
aynı tip ve/veya aynı şekilde işlenir. Bu işlem kolayca yapılır
yapı boyunca sistematik bir sıralama yolu olduğunda. Bu tür süreç-
ing, adresleme yöntemi olarak dinamik abonelik kullanılarak iyi bir şekilde desteklenir.
Veri değerlerinin toplanması heterojen olduğunda ve kayıtlar kullanılır.
farklı alanlar aynı şekilde işlenmez. Ayrıca, bir kaydın alanları
genellikle belirli bir sırayla işlenmesi gerekmez. Alan adları değişmez veya
sabit, indisler. Statik oldukları için çok verimli erişim sağlarlar.
tarlalara. Kayıt alanlarına erişmek için dinamik abonelikler kullanılabilir, ancak
tür denetimine izin vermez ve ayrıca daha yavaş olur.
Kayıtlar ve diziler, yerine getirmenin düşünceli ve verimli yöntemlerini temsil eder.
veri yapılarının iki ayrı ancak ilişkili uygulaması.
6.7.4 Kayıt Türlerinin Uygulanması
Kayıt alanları bitişik bellek konumlarında saklanır. Ama çünkü
alanların boyutları mutlaka aynı değildir, erişim yöntemi için kullanılan
diziler kayıtlar için kullanılmaz. Bunun yerine, başlangıca göre ofset adresi-
kaydın ning, her alan ile ilişkilidir. Alan erişimlerinin tümü işlenir
bu ofsetleri kullanarak. Bir kaydın derleme zamanı tanımlayıcısı, genel
Şekil 6.7'de gösterilen form. Kayıtlar için çalışma zamanı tanımlayıcıları gereksizdir.

Sayfa 301
280
Bölüm 6 Veri Tipleri
6.8 Grup Türleri
Tuple, elemanların birer kayıt olması dışında kayda benzer bir veri türüdür.
adlandırılmamış.
Python, değişmez bir demet türü içerir. Bir demetin değiştirilmesi gerekiyorsa,
list işleviyle bir diziye dönüştürülebilir . Değişiklikten sonra olabilir
tuple işleviyle bir Tuple'a geri dönüştürülür . Tuple'ların bir kullanımı ne zaman
bir diziye parametre olarak gönderildiğinde olduğu gibi, bir dizi yazmaya karşı korumalı olmalıdır.
harici işlev ve kullanıcı, işlevin değiştirilebilmesini istemiyor
parametre.
Python'un tupleleri, listeleriyle yakından ilişkilidir, ancak tuple'lar
değişmez. Aşağıdaki gibi, bir demet değişmez değeri atanarak bir demet oluşturulur
örnek:
myTuple = (3, 5.8, 'elma')
Bir demetin elemanlarının aynı tipte olması gerekmediğine dikkat edin.
Bir demetin elemanlarına, aşağıdaki gibi, parantez içinde indeksleme ile başvurulabilir.
devamındaki:
myTuple[1]
Bu, demetin ilk öğesine başvurur, çünkü demet indeksleme 1'de başlar .
Tuple'lar artı ( + ) operatörü ile sıralanabilir . Silinebilirler
ile del deyimi. Ayrıca başka operatörler ve işlevler de vardır.
tuples üzerinde çalıştırın.
ML, bir demet veri türü içerir. Bir ML demeti en az iki ele-
ments, oysa Python'un demetleri boş olabilir veya bir öğe içerebilir. De olduğu gibi
Şekil 6.7
Derleme zamanı
kayıt tanımlayıcısı
Adres
Telafi etmek
Tip
İsim
Telafi etmek
Tip
alan n
1. alan
İsim
Kayıt

Sayfa 302
6.9 Liste Türleri 281
Python, bir ML demeti, karışık türdeki öğeleri içerebilir. Aşağıdaki durum-
ment bir demet oluşturur:
val myTuple = (3, 5.8, 'elma');
Bir tanımlama grubu öğesi erişiminin sözdizimi aşağıdaki gibidir:
#1(myTuple);
Bu, demetin ilk elemanına atıfta bulunur.
ML'de yeni bir tanımlama grubu türü, aşağıdaki gibi bir tür bildirimi ile tanımlanabilir:
devamındaki:
tipi intReal = int * Gerçek ;
Bu tür değerler bir tamsayı ve bir gerçelden oluşur.
F# ayrıca tuple'lara sahiptir. Bir tanımlama grubu değeri atanarak bir tanımlama grubu oluşturulur.
virgülle ayrılmış ve parantezlerle ayrılmış ifadelerin bir listesi,
let ifadesinde isim . Bir demetin iki öğesi varsa, bunlara başvurulabilir.
sırasıyla fst ve snd işlevleriyle . Bir demetin elemanları
ikiden fazla öğeye genellikle solda bir demet deseni ile başvurulur
let ifadesinin tarafı . Bir demet deseni basitçe bir isim dizisidir, biri
sınırlayıcı parantezler olsun veya olmasın, demetin her bir öğesi. Zaman
Tuple deseni, let yapısının sol tarafıdır, çoklu bir atamadır. İçin
örneğin, aşağıdaki let yapılarını göz önünde bulundurun :
izin tup = (3, 5, 7) ;;
izin a, b, c = şahmerdan ;;
Bu atar 3 için bir , 5 için b ve 7 için c .
Tuple'lar Python, ML ve F#'ta fonksiyonların çoklu döndürmesine izin vermek için kullanılır.
uç değerler.
6.9 Liste Türleri
Listeler ilk olarak ilk işlevsel programlama dili olan LISP'de desteklendi.
Her zaman işlevsel dillerin bir parçası olmuşlardır, ancak son yıllarda
bazı zorunlu dillerde yollarını bulmuşlardır.
Şema ve Ortak LISP'deki listeler parantez ile sınırlandırılmıştır ve
öğeler herhangi bir noktalama işaretiyle ayrılmamıştır. Örneğin,
(ABCD)
İç içe listeler aynı forma sahip olduğundan,
(A (BC) D)

Sayfa 303
282
Bölüm 6 Veri Tipleri
Bu listede (BC) , dış listenin içine yerleştirilmiş bir listedir.
Veri ve kod, LISP'de ve onun soyundan gelenlerde aynı sözdizimsel biçime sahiptir.
Liste halinde (ABC) kodu olarak yorumlanır, bu işlev için bir çağrıdır A ile
parametreler B ve C .
Scheme'deki temel liste işlemleri, listeleri alan iki işlevdir.
ayrı ve iki liste oluşturan. ARAÇ fonksiyonu ilk elemanı döner onun
liste parametresi. Örneğin, aşağıdaki örneği göz önünde bulundurun:
(ARAÇ '(ABC))
Parametre listesinden önceki alıntı, yorumlayıcının düşünmesini önlemek içindir.
listeyi B ve C parametreleriyle A işlevine bir çağrı yapmak, bu durumda
onu yorumlayacaktı. CAR'a yapılan bu çağrı A döndürür .
CDR işlevi parametre listesine eksi ilk elemanını döner. İçin
örnek, aşağıdaki örneği göz önünde bulundurun:
(CDR '(ABC))
Bu işlev çağrısı (BC) listesini döndürür .
Common LISP ayrıca FIRST ( CAR ile aynı ), SECOND , SECOND işlevlerine sahiptir . . . ,
TENTH tarafından belirtilen liste parametrelerinin öğesini döndüren
onların isimleri.
Scheme ve Common LISP'de, CONS ile yeni listeler oluşturulur ve
LİSTE işlevleri. Fonksiyon EKSİLERİNİ iki parametre alır ve yeni bir döner
ilk parametresi birinci eleman, ikinci parametresi ise eleman olarak listelenir.
bu listenin geri kalanı. Örneğin, aşağıdakileri göz önünde bulundurun:
(EKSİ 'A'(M.Ö.))
Bu çağrı yeni listeyi (ABC) döndürür .
LİSTE fonksiyonu herhangi bir sayıda parametre alır ve yeni bir liste döndürür
öğeleri olarak parametrelerle. Örneğin, aşağıdaki çağrıyı düşünün
için LİSTESİ :
(LİSTESİ 'A 'B'(CD))
Bu çağrı yeni listeyi (AB (CD)) döndürür .
ML, görünümleri böyle olmasa da, listeler ve liste işlemlerine sahiptir.
Şema. Listeler, elemanlar ayrılmış olarak köşeli parantez içinde belirtilir.
virgülle, aşağıdaki tamsayı listesinde olduğu gibi:
[5, 7, 9]
[] , nil ile de belirtilebilecek boş listedir .
Scheme CONS işlevi, bir ikili infix operatörü olarak uygulanır.
ML, şu şekilde temsil edilir :: . Örneğin,
3:: [5, 7, 9]

Sayfa 304
6.9 Liste Türleri 283
aşağıdaki yeni listeyi döndürür: [3, 5, 7, 9] .
Bir listenin öğeleri aynı türde olmalıdır, bu nedenle aşağıdaki liste
yasa dışı olmak:
[5, 7.3, 9]
ML, Scheme'nin CAR ve CDR'sine karşılık gelen , hd adlı işlevlere sahiptir.
(kafa) ve tl (kuyruk). Örneğin,
hd [5, 7, 9] 5'tir
tl [5, 7, 9], [7, 9]
Scheme ve ML'deki listeler ve liste işlemleri şurada daha ayrıntılı olarak tartışılmaktadır:
15. Bölüm
F#'daki listeler, birkaç önemli farkla ML listeleriyle ilgilidir. Ele-
F# içindeki bir listenin öğeleri, virgül yerine noktalı virgülle ayrılır.
ML. hd ve tl işlemleri aynıdır, ancak yöntemler olarak adlandırılırlar.
Liste olarak sınıfı List.hd [1; 3; 5; 7] , bu 1 . EKSİLERİNİ
F# işlemi, ML'de olduğu gibi iki nokta olarak belirtilir.
Python, Python'un dizileri olarak da hizmet veren bir liste veri türü içerir.
Scheme, Common LISP, ML ve F# listelerinin aksine, Python listeleri
değişkendirler. Herhangi bir veri değeri veya nesne içerebilirler. Bir Python listesi oluşturulur
bir isme bir liste değeri ataması ile. Bir liste değeri, bir ifade dizisidir.
virgülle ayrılmış ve parantez ile ayrılmış Örneğin,
aşağıdaki ifadeyi dikkate alın:
myList = [3, 5.8, "üzüm"]
Bir listenin öğelerine, aşağıdaki gibi, parantez içindeki alt simgelerle başvurulur.
aşağıdaki örnek:
x = listem[1]
Bu ifade atar 5.8 için x . Bir listenin elemanları şundan başlayarak indekslenir:
sıfır. Liste öğeleri atama yoluyla da güncellenebilir. Bir liste öğesi olabilir
aşağıdaki ifadede olduğu gibi del ile silindi :
del myList[1]
Bu ifade myList öğesinin ikinci öğesini kaldırır .
Python, list com adı verilen diziler oluşturmak için güçlü bir mekanizma içerir.
kavrayışlar . Bir liste kavrayışı, küme gösteriminden türetilen bir fikirdir. ilk o
işlevsel programlama dili Haskell'de göründü (bkz. Bölüm 15).
Liste kavrayışının mekaniği, her birine bir işlevin uygulanmasıdır.
belirli bir dizinin öğeleri ve sonuçlardan yeni bir dizi oluşturulur.
Python liste kavrayışının sözdizimi aşağıdaki gibidir:

Sayfa 305
284
Bölüm 6 Veri Tipleri
[sentezleme için iterate_var içinde dizi halinde durumu]
Aşağıdaki örneği göz önünde bulundurun:
[x * X için X aralığında (12) , eğer x% 3 == 0]
Aralık fonksiyonu dizisi oluşturur [0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
10, 11, 12] . Koşullu, dizideki tüm sayıları filtreler.
3 ile tam bölünemez . Ardından, ifade kalan sayıların karesini alır.
Kare almanın sonuçları, döndürülen bir dizide toplanır. Bu
liste anlama aşağıdaki diziyi döndürür:
[0, 9, 36, 81]
Python'da liste dilimleri de desteklenir.
Haskell'in liste kavrayışları aşağıdaki forma sahiptir:
[ vücut | elemeler ]
Örneğin, bir listenin aşağıdaki tanımını göz önünde bulundurun:
[n * n | n <- [1..10]]
Bu numaralar karelerinden oluşan bir listesi tanımlar 1 için 10 .
F#, o dilde de kullanılabilen liste anlamalarını içerir
diziler oluşturmak için. Örneğin, aşağıdaki ifadeyi göz önünde bulundurun:
let myArray = [|i için 1 .. 5 -> (i * i) |];;
Bu ifade [1; 4; 9; 16; 25] ve onu myArray olarak adlandırır .
C# ve Java'nın genel yığın dinamiklerini desteklediğini Bölüm 6.5'ten hatırlayın
koleksiyon sınıfları , sırasıyla List ve ArrayList . Bu yapılar
aslında listeler.
6.10 Birlik Türleri
Bir birlik olan değişkenlerin bir tür farklı farklı türü değerleri depolayabilir olduğu
Program yürütme sırasındaki süreler. Bir birlik türü ihtiyacına örnek olarak,
sabitleri depolamak için kullanılan bir derleyici için bir sabitler tablosu düşünün
derlenmekte olan bir programda bulunur. Her tablo girişinin bir alanı,
sabitin değeri. Diyelim ki derlenmekte olan belirli bir dil için,
sabit türleri tamsayı, kayan nokta ve Booleandı. Açısından
tablo yönetimi, aynı yer, bir tablo alanı varsa uygun olur,
bu üç türden herhangi birinin değerini depolayabilir. O zaman tüm sabit değerler olabilir
aynı şekilde ele alınacaktır. Böyle bir yerin türü, bir bakıma,
saklayabileceği üç değer türünün birleşimi.

Sayfa 306
6.10 Birlik Tipleri 285
6.10.1 Tasarım Sorunları
Bölüm 6.12'de tartışılan birleşim tiplerinin tip kontrolü problemi,
büyük bir tasarım sorununa yol açar. Diğer temel soru, nasıl
sözdizimsel olarak bir birliği temsil eder. Bazı tasarımlarda, birlikler parça olarak sınırlandırılmıştır.
kayıt yapılarının, ancak diğerlerinde değildir. Bu nedenle, birincil tasarım sorunları
sendika türlerine özgü olanlar şunlardır:
• Tip kontrolü gerekli mi? Bu tür herhangi bir tip kontrolünün
dinamik ol.
• Sendikalar kayıtlara gömülmeli mi?
6.10.2 Ayrımcılığa Karşı Özgür Sendikalar
C ve C++ dil desteği olmayan birleşim yapıları sağlar
tip kontrolü için. C ve C++'da birleşim yapısı birliği belirtmek için kullanılır.
yapılar. Bu dillerdeki birleşimlere özgür birlikler denir , çünkü pro-
gramerlerin kullanımlarında tip kontrolünden tamamen bağımsız olmalarına izin verilir. İçin
örneğin, aşağıdaki C birliğini göz önünde bulundurun:
birlik flexType {
int intEl;
şamandıra şamandırasıEl ;
};
birleşim flexType el1;
yüzer x;
. . .
el1.intEl = 27;
x = el1.floatEl;
Bu son atamanın türü kontrol edilmez, çünkü sistem bunu belirleyemez.
el1'in geçerli değerinin geçerli türü , bu nedenle bit dizisi temsilini atar.
ait sentation 27 için şamandıra değişken x elbette saçmalıktır.
Birleşimlerin tür denetimi, her birleşim yapısının bir tür içermesini gerektirir.
gösterge. Böyle bir göstergeye etiket veya ayrımcı denir ve
ayrımcıya ayrımcı birlik denir . sağlayan ilk dil
ayrımcılığa uğrayan sendikalar ALGOL 68 idi. Şimdi Ada, ML,
Haskell ve F#.
6.10.3 Ada Birlik Tipleri
Ayrımcı sendikalar için Ada tasarımı, önceki modellere dayalıdır.
cessor dili, Pascal, kullanıcının bir varyant kaydının değişkenlerini belirlemesine izin verir.
varyantta olası tür değerlerinden yalnızca birini depolayacak tür. Bunda
Böylece kullanıcı, tip denetiminin ne zaman statik olabileceğini sisteme söyleyebilir. böyle bir
Kısıtlı değişken olarak adlandırılır kısıtlı varyant değişken .

Sayfa 307
286
Bölüm 6 Veri Tipleri
Kısıtlanmış bir değişken değişkeninin etiketi, adlandırılmış bir sabit gibi ele alınır.
Ada'daki kısıtlanmamış varyant kayıtları, varyantlarının değerlerinin değişmesine izin verir
yürütme sırasında türleri. Ancak, varyantın türü yalnızca şu şekilde değiştirilebilir:
Diskriminant dahil tüm kaydın atanması. Bu tutarsızlığa izin vermez
çünkü yeni atanan kayıt sabit bir veri toplamıysa, değer
etiketin boyutu ve varyantın türü tutarlılık açısından statik olarak kontrol edilebilir. 7 ise
atanan değer bir değişkendir, atandığında tutarlılığı garanti edilmiştir,
bu nedenle, şimdi atanmakta olan değişkenin yeni değerinin tutarlı olacağından emin olabilirsiniz.
Aşağıdaki örnek, bir Ada varyant kaydını göstermektedir:
type Shape is (Daire, Üçgen, Dikdörtgen);
türü Renk olan (kırmızı, yeşil, mavi);
tip Şekil (Şekil Formu) olduğu
kayıt
Doldurulmuş: Boole;
Renk : Renkler;
vaka Form (şimdiki değeri)
ne zaman Daire =>
Çap : Şamandıra;
ne zaman Üçgen =>
Left_Side : Tamsayı;
Right_Side : Tamsayı;
Açı : Şamandıra;
ne zaman Dikdörtgen =>
Side_1 : Tamsayı;
Side_2 : Tamsayı;
son durum ;
kayıt sonu ;
Bu varyant kaydının yapısı Şekil 6.8'de gösterilmektedir. Aşağıdaki iki
ifadeler, Şekil türündeki değişkenleri bildirir :
Şekil_1 : Şekil;
Şekil_2 : Şekil(Form => Üçgen);
Figure_1 , başlangıç ​​değeri olmayan sınırlandırılmamış bir değişken kaydı olarak bildirildi
değer. Türü, dis dahil olmak üzere bütün bir kaydın atanmasıyla değişebilir.
suçlu, aşağıdaki gibi:
Figure_1 := (Dolu => Doğru,
Renk => Mavi,
Form => Dikdörtgen,
Yan_1 => 12,
Side_2 => 3);
7. Tutarlılık, eğer etiket, birliğin mevcut tipini Tamsayı olarak gösteriyorsa,
birliğin mevcut değeri aslında Tamsayı'dır.

Sayfa 308
6.10 Birlik Tipleri 287
Bu atamanın sağ tarafı bir veri toplamıdır.
Figure_2 değişkeni , bir üçgen olarak sınırlandırılmış olarak bildirildi ve yapılamaz.
başka bir varyantla değiştirilebilir.
Bu ayrımcı birlik biçimi güvenlidir, çünkü her zaman izin verir.
kısıtlamasız değişkenlerdeki alanlara referanslar olmasına rağmen tip kontrolü
dinamik olarak kontrol edilmelidir. Örneğin, aşağıdakilere sahip olduğumuzu varsayalım
Beyan:
if (Şekil_1.Çap > 3.0) . . .
olup olmadığını belirlemek için çalışma zamanı sisteminin Figure_1'i kontrol etmesi gerekir.
onun Formu etiketi oldu Çember . Değilse, başvurulacak bir tür hatası olurdu
onun Çapı .
6.10.4 F#'da Birleşimler
Bir birleşim, F#'da OR operatörleri ( | ) kullanılarak bir tür ifadesiyle bildirilir .
bileşenleri tanımlar. Örneğin, aşağıdakilere sahip olabiliriz:
tip intReal =
| İntValue ait int
| RealValue ait şamandıra ;;
Bu örnekte, intReal birleşim türüdür. İntValue ve RealValue vardır
yapıcılar. İntReal türündeki değerler, yapıcılar kullanılarak şu şekilde oluşturulabilir:
bunlar bir fonksiyon olsaydı, aşağıdaki örneklerde olduğu gibi: 8
izin IR1 = intValue 17 ;;
let IR2 RealValue 3.4 = ;;
8. let ifadesi, adlara değer atamak ve statik bir kapsam oluşturmak için kullanılır; çift
noktalı virgül, F# etkileşimli yorumlayıcısı kullanıldığında ifadeleri sonlandırmak için kullanılır.
Şekil 6.8
Ayrımcı bir sendika
üç şekil değişkeninden
(tüm değişkenleri varsayalım
aynı boyutta)
Diskriminant (Form)
Daire: Çap
Dikdörtgen: Side_1, Side_2
Üçgen: Left_Side, Right_Side, Açı
Renk
Dolu

Sayfa 309
288
Bölüm 6 Veri Tipleri
Bir birliğin değerine erişim, model eşleştirme yapısıyla yapılır.
F#'da kalıp eşleştirme, eşleşen ayrılmış kelime ile belirtilir . Genel
yapının formu aşağıdaki gibidir:
maç deseni ile
| ifade_listesi 1 - > ifade 1
| . . .
| ifade_listesi n - > ifade n
Desen herhangi bir veri türü olabilir. İfade listesi joker karakter içerebilir
karakter ( _ ) veya yalnızca bir joker karakter olabilir. Örneğin, şunu düşünün:
aşağıdaki eşleşme yapısı:
izin bir 7 = ;;
let b = "üzüm" ;;
izin X = eşleşme (a, b) ile
| 4, "elma" -> elma
| _, "üzüm" -> üzüm
| _ -> meyve;;
intReal birliğinin türünü görüntülemek için aşağıdaki işlev
kullanılacak:
printType değerine izin ver =
eşleşecek değeri ile
| IntValue değeri -> printfn "Bu bir tamsayıdır"
| RealValue değeri -> printfn "Bu bir kayan noktadır";;
Aşağıdaki satırlar bu işleve yapılan çağrıları ve çıktıyı gösterir:
printType ir1;;
bu bir tamsayıdır
printType ir2;;
bu bir şamandıra
6.10.5 Değerlendirme
Birlikler, bazı dillerde potansiyel olarak güvenli olmayan yapılardır. Onlar
C ve C++'ın güçlü bir şekilde yazılmamasının nedenlerinden biri: Bu diller
birliklerine yapılan referansların tip kontrolüne izin vermeyin. Diğer taraftan, başka bir açıdan
el, birlikler Ada, ML, Haskell'deki tasarımlarında olduğu gibi güvenle kullanılabilir,
ve F#.
Ne Java ne de C#, artan büyümeyi yansıtabilecek sendikaları içermez.
bazı programlama dillerinde güvenlik endişesi.

Sayfa 310
6.11 İşaretçi ve Referans Türleri 289
6.10.6 Birlik Türlerinin Uygulanması
Sendikalar, mümkün olan her şey için aynı adresi kullanarak uygulanır.
varyant. En büyük değişken için yeterli depolama ayrılmıştır. Bir dis etiketi-
Suçlu birlik, varyantla birlikte kayıt benzeri bir yapıda saklanır.
Derleme zamanında, her bir varyantın tam açıklaması saklanmalıdır.
Bu, bir vaka tablosunu tanımlayıcıdaki etiket girişiyle ilişkilendirerek yapılabilir.
Vaka tablosu, her bir varyant için bir tanımlayıcıya işaret eden bir girdiye sahiptir.
bu özel varyant. Bu düzenlemeyi göstermek için aşağıdakileri göz önünde bulundurun
Ada örneği:
yazın : Düğüm (Boolean Etiketi) olduğunu
kayıt
vaka Etiketi olduğu
True olduğunda => Say : Tamsayı;
zaman yanlış => Sum: Float;
son durum ;
kayıt sonu ;
Bu tip için tanımlayıcı Şekil 6.9'da gösterilen forma sahip olabilir.
Şekil 6.9
Derleme zamanı
bir için tanımlayıcı
ayrımcı sendika
Adres
Telafi etmek
BOOLE
Etiket
ayrımcı sendika
vaka tablosu
İsim
Tip
İsim
Tip
Doğru
YANLIŞ
Saymak
tamsayı
toplam
Batmadan yüzmek
6.11 İşaretçi ve Referans Türleri
Bir işaretçi türü olan değişkenler oluşur değerlerinin bir aralığı vardır biridir
bellek adresleri ve özel bir değer, nil . nil değeri geçerli bir adres değil
ve bir işaretçinin şu anda bir referansa başvurmak için kullanılamayacağını belirtmek için kullanılır.
hafıza hücresi.
İşaretçiler iki farklı kullanım türü için tasarlanmıştır. İlk olarak, işaretçiler sağlar
Montajda sıklıkla kullanılan dolaylı adresleme gücünün bir kısmı
dil programlama İkincisi, işaretçiler dinamikleri yönetmek için bir yol sağlar.
depolamak. Depolamanın yapıldığı bir alandaki bir konuma erişmek için bir işaretçi kullanılabilir.
dinamik olarak ayrılmış bir yığın olarak adlandırılır .

Sayfa 311
290
Bölüm 6 Veri Tipleri
Dinamik olarak yığından ayrılır Değişkenler denir yığın -
dinamik değişkenler . Genellikle kendileriyle ilişkili tanımlayıcıları yoktur.
ve bu nedenle yalnızca işaretçi veya başvuru tipi değişkenler tarafından başvurulabilir. Değişkenler
adsız değişkenlere adsız değişkenler denir . Bu son uygulamada
en önemli tasarım konularının ortaya çıktığı işaretçiler alanı.
İşaretçiler, dizilerden ve kayıtlardan farklı olarak, yapılandırılmış türler değildirler.
bir tür operatörü ( C ve C++'da * ve Ada'da erişim ) kullanılarak tanımlanır. Kürk-
termore, aynı zamanda skaler değişkenlerden farklıdırlar çünkü
verileri depolamak için kullanılmak yerine başka bir değişkene başvurun. Bu ikisi
değişken kategorilerine sırasıyla referans türleri ve değer türleri denir .
Her iki tür işaretçi kullanımı da bir dile yazılabilirlik ekler. Örneğin,
ikili ağaç gibi dinamik bir yapı uygulamanın gerekli olduğunu varsayalım.
işaretçileri olmayan Fortran 77 gibi bir dil. Bu gerektirir
programcı, mevcut ağaç düğümlerinin bir havuzunu sağlamak ve sürdürmek için
muhtemelen paralel dizilerde uygulanacaktır. Ayrıca eksikliğinden dolayı
Fortran 77'de dinamik depolama, programcının
gerekli düğümlerin maksimum sayısını tahmin edin. Bu açıkça garip ve
ikili ağaçlarla başa çıkmanın hataya açık yolu.
Bölüm 6.11.6'da tartışılan referans değişkenler yakından
işaretçiler ile ilgili.
6.11.1 Tasarım Konuları
İşaretçilere özel birincil tasarım sorunları şunlardır:
• Bir işaretçi değişkeninin kapsamı ve ömrü nedir?
• Yığın dinamik bir değişkenin ömrü nedir (bir işaretçi değeri
Referanslar)?
• İşaretçiler, işaret edebilecekleri değer türüyle sınırlı mı?
• Dinamik depolama yönetimi, dolaylı adresleme,
ya da her ikisi de?
• Dil, işaretçi türlerini, başvuru türlerini veya her ikisini de desteklemeli mi?
6.11.2 İşaretçi İşlemleri
İşaretçi türü sağlayan diller genellikle iki temel işaretçi içerir.
işlemler: atama ve referans kaldırma. İlk işlem bir işaretçi ayarlar
bazı yararlı adreslere değişkenin değeri. İşaretçi değişkenleri yalnızca
operatör tarafından olsun, dinamik depolamayı, ardından tahsis mekanizmasını yönetin
veya yerleşik alt program, işaretçi değişkenini başlatmaya yarar. işaretçiler ise
yığın dinamik olmayan değişkenlere dolaylı adresleme için kullanılır, o zaman orada
adresini almak için açık bir operatör veya yerleşik alt program olmalıdır.
daha sonra işaretçi değişkenine atanabilecek bir değişken.
Bir ifadede bir işaretçi değişkeninin oluşumu şu şekilde yorumlanabilir:
iki farklı yol. İlk olarak, içeriğe bir referans olarak yorumlanabilir.

Sayfa 312
6.11 İşaretçi ve Referans Tipleri 291
bağlı olduğu bellek hücresinin, bir işaretçi durumunda bir
adres. Bu, bir ifadedeki işaretçi olmayan bir değişkenin tam olarak nasıl olacağıdır.
yorumlanır, ancak bu durumda değeri muhtemelen bir adres olmayacaktır.
Bununla birlikte, işaretçi, içindeki değere bir referans olarak da yorumlanabilir.
işaretçi değişkeninin bulunduğu bellek hücresinin gösterdiği bellek hücresi
sınırdır. Bu durumda, işaretçi dolaylı bir başvuru olarak yorumlanır. bu
eski durum normal bir işaretçi referansıdır; ikincisi dereferenc'in sonucudur.
ing işaretçisi. Bir seviye üzerinden referans alan referans kaldırma
dolaylı, ikinci temel işaretçi işlemidir.
İşaretçilerin referanslarının kaldırılması açık veya örtük olabilir. Fortran'da 95+
örtüktür, ancak diğer birçok çağdaş dilde, yalnızca şu durumlarda ortaya çıkar:
açıkça belirtilmiştir. C++'da yıldız işareti ( * ) ile açıkça belirtilir.
önek tekli operatör. Aşağıdaki referans kaldırma örneğini düşünün: If ptr
7080 değerine sahip bir işaretçi değişkendir ve adresi 7080 olan hücre
206 değeri, ardından atama
j = *ptr
setleri j 206 Bu işlem, Şekil 6.10 gösterilmiştir.
Şekil 6.10
Görev
j işlemi = *ptr
7080
7080
ptr
J
anonim
dinamik değişken
206
İşaretçiler kayıtları gösterdiğinde, alanlara yapılan başvuruların sözdizimi
Bu kayıtların yüzdesi diller arasında farklılık göstermektedir. C ve C++'da iki yol vardır:
bir kaydın işaretçisi, o kayıttaki bir alana başvurmak için kullanılabilir. bir işaretçi ise
p değişkeni age , (*p) adlı bir alana sahip bir kaydı işaret eder .
o alana bakın. -> operatörü , bir kayda işaretçi arasında kullanıldığında
ve bu kaydın bir alanı, referans kaldırma ve alan referansını birleştirir. İçin
örneğin, ekspresyon s -> yaş eşdeğerdir (* p) .age . Ada olarak, p.age
kullanılabilir, çünkü işaretçilerin bu tür kullanımları dolaylı olarak kaldırılmıştır.
Bir yığının yönetimi için işaretçiler sağlayan diller,
açık bir tahsis işlemi içerir. Tahsis bazen ile belirtilir
C'deki malloc gibi bir alt program. Nesne yönelimli destekleyen dillerde
programlama, yığın nesnelerinin tahsisi genellikle yeni işlemle belirtilir.
tor. Örtük ayırma sağlamayan C++, silme işlevini kullanır .
ayırma operatörü

Sayfa 313
292
Bölüm 6 Veri Tipleri
6.11.3 İşaretçi Sorunları
İşaretçi değişkenlerini içeren ilk yüksek seviyeli programlama dili,
Her iki yığın dinamik değişkene atıfta bulunmak için işaretçilerin kullanılabileceği PL/I
ve diğer program değişkenleri. PL/I'nin göstergeleri oldukça esnekti, ancak
kullanımları çeşitli programlama hatalarına yol açabilir. Bazı prob-
PL/I işaretçileri, sonraki dillerin işaretçilerinde de mevcuttur.
Java gibi bazı yeni diller, işaretçileri tamamen
örtük serbest bırakma ile birlikte, maliyeti en aza indiren referans türleri
işaretçiler ile Mary sorunları. Bir referans türü gerçekten sadece bir işaretçidir.
kısıtlı operasyonlar
6.11.3.1 Sarkan İşaretçiler
Bir sarkan işaretçi veya sarkan bir referans içeren bir işaretçidir
ayırmanın bir yığın-dinamik değişkenin adresi. sarkan
işaretçiler birkaç nedenden dolayı tehlikelidir. İlk olarak, işaret edilen yer
bazı yeni yığın dinamik değişkene yeniden tahsis edilmiş olabilir. Eğer
yeni değişken eskisi ile aynı tipte değil, tip kontrolleri
sarkan işaretçi geçersiz. Yeni dinamik değişken aynı olsa bile
yazın, yeni değerinin eski işaretçinin iptali ile hiçbir ilişkisi olmayacaktır.
bahsi geçen değer. Ayrıca, ekranı değiştirmek için sarkan işaretçi kullanılıyorsa,
yığın dinamik değişken, yeni yığın dinamik değişkenin değeri
yerlebir edilmiş. Son olarak, konumun şu anda geçici olarak olması mümkündür.
depolama yönetim sistemi tarafından, muhtemelen bir zincirde bir işaretçi olarak kullanılır.
kullanılabilir depolama blokları, böylece konum değişikliğine neden olur
depolama yöneticisi başarısız olur.
Aşağıdaki işlem dizisi, birçok durumda sarkan bir işaretçi oluşturur.
Diller:
1. Yeni bir yığın dinamik değişken oluşturulur ve p1 işaretçisi şu noktaya ayarlanır
ona.
2. İşaretçi p2 atanan p1 ‘in değeri.
3. p1 ile gösterilen yığın dinamik değişkeni açıkça serbest bırakılır
(muhtemelen ayar p1 için nil ), ancak , p2 işlemi ile değiştirilmez. p2
artık sarkan bir işaretçi. Serbest bırakma işlemi değişmediyse
p1 , hem p1 ve p2 sarkan olacaktır. (Tabii ki bu bir
takma — p1 ve p2 takma adlardır.)
Örneğin, C++'da aşağıdakilere sahip olabiliriz:
int * diziPtr1;
int * diziPtr2 = yeni int [100];
diziPtr1 = diziPtr2;
sil [] diziPtr2;
// Şimdi, diziPtr1 sarkıyor, çünkü yığın depolama
// işaret ettiği yer ayrıldı.

Sayfa 314
6.11 İşaretçi ve Referans Türleri 293
C++'da hem arrayPtr1 hem de arrayPtr2 artık sarkık işaretçilerdir, çünkü
C++ silme operatörünün işlenen işaretçisinin değeri üzerinde hiçbir etkisi yoktur. İçinde
C++, bir atama ile bir silme operatörünü takip etmek yaygındır (ve güvenlidir).
sıfırı temsil eden sıfır, işaret edilen değeri olan işaretçiye
ayrılmış.
Dinamik değişkenlerin açık bir şekilde serbest bırakılmasının nedeninin olduğuna dikkat edin.
sarkan işaretçiler.
6.11.3.2 Kayıp Yığın Dinamik Değişkenleri
Bir kayıp yığın-dinamik değişken bir tahsis yığın-dinamiktir
artık kullanıcı programı tarafından erişilemeyen değişken. Çok
değişkenler genellikle çöp olarak adlandırılır , çünkü yararlı değildirler
orijinal amaçları için ve ayrıca yeniden tahsis edilemezler
programda bazı yeni kullanımlar için. Kayıp yığın dinamik değişkenler
genellikle aşağıdaki işlem dizisiyle oluşturulur:
1. İşaretçi p1 yeni oluşturulan yığın dinamiğine işaret edecek şekilde ayarlanmıştır.
değişken.
2. p1 daha sonra yeni oluşturulan başka bir yığın dinamiğine işaret edecek şekilde ayarlanır
değişken.
İlk yığın dinamik değişkeni artık erişilemez veya kaybolmuştur.
Buna bazen bellek sızıntısı denir . Bellek sızıntısı
dilin örtük veya örtük kullanıp kullanmadığına bakılmaksızın bir sorun
açık ayırma. Aşağıdaki bölümlerde, araştırıyoruz
dil tasarımcıları sarkma sorunlarıyla nasıl başa çıktı?
işaretçiler ve kayıp yığın dinamik değişkenler.
6.11.4 Ada'daki İşaretçiler
Ada'nın işaretçilerine erişim türleri denir . Sarkan işaretçi sorunu,
Ada'nın tasarımıyla, en azından teoride, kısmen hafifletildi. Yığın dinamik bir değişken
sonunda (uygulayıcının tercihine bağlı olarak) örtük olarak serbest bırakılabilir.
işaretçi türünün kapsamı; böylece, açık bir şekilde ihtiyacı önemli ölçüde azaltır
serbest bırakma. Bununla birlikte, Ada derleyicilerinden herhangi biri bu gar-
bage koleksiyonu, bu nedenle avantaj neredeyse her zaman sadece teoridedir. Çünkü
yığın dinamik değişkenlere yalnızca bir türdeki değişkenler tarafından erişilebilir.
bu tür bildiriminin kapsamının sonuna ulaşıldı, hiçbir işaretçi olamaz
dinamik değişkeni işaret eden sola. Bu sorunu azaltır, çünkü
uygun olmayan şekilde uygulanan açık serbest bırakma, sarkmanın ana kaynağıdır
işaretçiler. Ne yazık ki, Ada dilinin de açık bir ayırıcısı vardır,
Unchecked_Deallocation . Adı, kullanımını caydırmak içindir veya
en azından kullanıcıyı olası sorunları konusunda uyarın. Unchecked_Deallocation
sarkan işaretçilere neden olabilir.
Kayıp yığın dinamik değişken sorunu Ada'nın tasarımıyla ortadan kaldırılmaz
işaretçiler.
tarih notu
Pascal açık bir
serbest bırakma operatörü: elden çıkarın.
sorunu nedeniyle
neden olduğu sarkan işaretçiler
atın, bazı Pascal uygulamaları
tations basitçe yok sayıldı
bir programda göründüğünde.
Her ne kadar bu etkili bir şekilde ön-
havalandırma delikleri sarkan işaretçiler, aynı zamanda
yığın deposunun yeniden kullanılmasına izin vermez.
programın artık olmadığı yaş
ihtiyaçlar. Pascal'ın in-
tially bir öğret-
bir dil olarak değil,
endüstriyel alet.

Sayfa 315
294
Bölüm 6 Veri Tipleri
6.11.5 C ve C++'da İşaretçiler
C ve C++'da işaretçiler, adreslerde kullanılanlarla aynı şekillerde kullanılabilir.
derleme dilleri. Bu, son derece esnek oldukları ancak kullanılmaları gerektiği anlamına gelir.
büyük bir özenle. Bu tasarım, sarkan işaretçiye veya kaybolmaya hiçbir çözüm sunmaz
yığın dinamik değişken problemleri. Ancak, işaretçi aritmetiğinin
C ve C++'da mümkün olması, işaretçilerini diğerlerinden daha ilginç hale getirir.
diğer programlama dilleri.
C ve C++ işaretçileri, nereye ayrıldığına bakılmaksızın herhangi bir değişkeni işaret edebilir.
katılmış. Aslında, bir değişken olsun ya da olmasın bellekte herhangi bir yeri işaret edebilirler.
orada ya da değil, bu tür işaretçilerin tehlikelerinden biri.
C ve C++'da yıldız işareti ( * ) başvuru kaldırma işlemini belirtir ve
ve işareti ( & ), bir değişkenin adresini üreten operatörü belirtir.
Örneğin, aşağıdaki kodu göz önünde bulundurun:
int *ptr;
int sayısı, başlangıç;
. . .
ptr = &init;
say = *ptr;
ptr değişkenine atama, onu init adresine ayarlar . atama-
oluşması için sayısı dereferences ptr de değerinin üretilmesi için init daha sonra,
saymakla görevlendirilmiştir . Bu nedenle, iki atama ifadesinin etkisi, atamaktır.
değeri init için saymak . Bir işaretçi bildiriminin belirttiğine dikkat edin
onun etki alanı türü.
Yukarıdaki iki atama ifadesinin eşdeğer olduklarına dikkat edin.
tek atamaya sayma etkisi
say = başlangıç;
İşaretçilere, doğru değişkenin herhangi bir değişkeninin adres değeri atanabilir.
etki alanı türü veya bunlara nil için kullanılan sıfır sabiti atanabilir .
İşaretçi aritmetiği, bazı sınırlı biçimlerde de mümkündür. Örneğin,
eğer ptr bazı bazı değişkene noktaya ilan edilen bir işaretçi değişkeni
veri türü, ardından
ptr + dizin
yasal bir ifadedir. Böyle bir ifadenin semantiği aşağıdaki gibidir.
Bunun yerine sadece değerini ekleyerek endeksine göre ptr , değeri endeksi ise
İlk (bellek birimleri) hafıza hücresinin boyutu ile ölçeklenmiş olduğu ptr
işaret ediyor (temel türü). Örneğin, ptr için bir bellek hücresine işaret ediyorsa
boyutu dört bellek birimi olan bir tür, ardından dizin 4 ile çarpılır ve
sonuç ptr'ye eklenir . Bu tür adreslemelerin temel amacı arit-
metik, dizi manipülasyonudur. Aşağıdaki tartışma tek-
yalnızca boyutlandırılmış diziler.

Sayfa 316
6.11 İşaretçi ve Referans Tipleri 295
C ve C++'da tüm diziler, alt indislerinin alt sınırı olarak sıfır kullanır.
aralıklar ve alt simge içermeyen dizi adları her zaman
ilk eleman. Aşağıdaki beyanları göz önünde bulundurun:
int listesi [10];
int *ptr;
ödevi düşünün
ptr = liste;
bunlardan adresi atar listesi [0] ile ptr , çünkü a olmayan bir dizi ismi
indis dizinin temel adresi olarak yorumlanır. Bu görev verildiğinde,
aşağıdakiler doğrudur:
*(ptr + 1) , list[1] ile eşdeğerdir .
*(ptr + index) , list[index] ile eşdeğerdir .
ptr[index] , list[index] ile eşdeğerdir .
Bu ifadelerden, işaretçi işlemlerinin aynı işlemleri içerdiği açıktır.
indeksleme işlemlerinde kullanılan ölçekleme. Ayrıca, dizilere işaretçiler şunları yapabilir:
dizi adlarıymış gibi dizine eklenebilir.
C ve C++'daki işaretçiler, işlevlere işaret edebilir. Bu özellik geçmek için kullanılır
diğer işlevlere parametre olarak işlev görür. İşaretçiler ayrıca parametre için kullanılır
Bölüm 9'da tartışıldığı gibi geçer.
C ve C++ , değerlerine işaret edebilen void * türünde işaretçiler içerir .
her hangi bir tür. Aslında genel işaretçilerdir. Ancak, tip denetimi bir
void * işaretçileriyle ilgili sorun , çünkü bu diller referans kaldırmaya izin vermiyor
onlara. void * işaretçilerinin yaygın bir kullanımı , parametre türleri gibidir.
bellekte çalışan işlevler. Örneğin, bir işlev istediğimizi varsayalım.
bir dizi bayt veriyi bellekteki bir yerden başka bir yere taşıma.
Herhangi bir türden iki işaretçiden geçirilebilseydi en genel olurdu. Bu
fonksiyondaki karşılık gelen resmi parametreler olsaydı yasal olurdu
geçersiz * yazın. İşlev daha sonra bunları char * türüne dönüştürebilir ve
gerçek parametreler olarak hangi tür işaretçilerin gönderildiğine bakılmaksızın işlem.
6.11.6 Referans Tipleri
Bir referans türü değişkeni, bir işaretçiye benzer, önemli ve
temel fark: Bir işaretçi, bellekteki bir adresi ifade ederken, bir
başvuru, bellekteki bir nesneyi veya değeri ifade eder. Sonuç olarak, öyle olmasına rağmen
adreslerde aritmetik yapmak doğal, aritmetik yapmak mantıklı değil
referanslar hakkında.
C++, öncelikle aşağıdakiler için kullanılan özel bir başvuru türü içerir.
fonksiyon tanımlarında formal parametreler. Bir C++ başvuru tipi değişkeni, bir
her zaman örtük olarak başvurulan sabit işaretçi. Çünkü bir C++ referansı-
ence tipi değişken bir sabittir, bazılarının adresi ile başlatılmalıdır.

Sayfa 317
296
Bölüm 6 Veri Tipleri
tanımındaki değişkendir ve başlatmadan sonra bir referans tipi değişkeni
asla başka bir değişkene referans verecek şekilde ayarlanmaz. Örtük başvuru, engeller
bir referans değişkenin adres değerine atama.
Referans tipi değişkenler, tanımlarında önlerine getirilerek belirtilir.
ve işareti ( & ) olan isimler . Örneğin,
int sonuç = 0;
int &ref_result = sonuç;
. . .
başvuru_sonuç = 100;
Bu kod kesiminde, sonuç ve başvuru_sonucu takma adlardır .
İşlev tanımlarında resmi parametreler olarak kullanıldığında, C++ referansı
türleri, arayan işlevi ile arasında iki yönlü iletişim sağlar.
çağrılan işlev. Bu, işaretçi olmayan ilkel parametrelerle mümkün değildir.
eter türleri, çünkü C++ parametreleri değere göre iletilir. işaretçi geçmek
parametre olarak aynı iki yönlü iletişimi gerçekleştirir, ancak işaretçi
resmi parametreler, kodun daha az okunmasını sağlayan açık referans kaldırma gerektirir.
mümkün ve daha az güvenli. Referans parametrelere çağrılan işlevde başvurulur.
tam olarak diğer parametreler gibi. Çağıran işlevin belirtmesi gerekmez
karşılık gelen biçimsel parametresi bir referans türü olan bir parametre
olağandışı bir şey mi. Derleyici, değerler yerine adresleri iletir.
referans parametreleri.
C++ üzerinde daha fazla güvenlik arayışında, Java tasarımcıları
Tamamen C++ tarzı işaretçiler. C++ referans değişkenlerinden farklı olarak, Java referansı
değişkenler, farklı sınıf örneklerine atıfta bulunmak üzere atanabilir; onlar con değil
stantlar. Tüm Java sınıfı örneklerine başvuru değişkenleri tarafından başvurulur. Yani,
aslında, Java'da referans değişkenlerin tek kullanımı. Bu konular daha
Bölüm 12'de tartışılmıştır.
Aşağıda, String standart bir Java sınıfıdır:
dize str1;
. . .
str1 = "Bu bir Java değişmez dizesidir";
Bu kodda, str1 bir String sınıfı örneğine referans olarak tanımlanır veya
nesne. Başlangıçta null olarak ayarlanır. Sonraki atama, str1'i referans olarak ayarlar-
ence dize nesne, "Bu bir Java değişmez dizesi" .
Java sınıfı örnekleri örtük olarak serbest bırakıldığından (açık
ayırma operatörü), Java'da sarkan referanslar olamaz.
C#, hem Java başvurularını hem de C++ işaretçilerini içerir. Ancak
işaretçilerin kullanılması kesinlikle önerilmez. Aslında, işaretçiler kullanan herhangi bir alt program
güvenli olmayan değiştiriciyi içermelidir . Dikkat edin, nesneler referansla gösterilse de-
enceler örtük olarak serbest bırakılır, bu, işaretçilerle gösterilen nesneler için doğru değildir.
İşaretçiler, öncelikle C# programlarının birlikte çalışmasına izin vermek için C#'a dahil edildi.
C ve C++ kodu.

Sayfa 318
6.11 İşaretçi ve Referans Tipleri 297
Smalltalk, Python, Ruby ve nesne yönelimli dillerdeki tüm değişkenler
Lua referanstır. Her zaman örtük olarak başvurudan çıkarılırlar. Ayrıca,
bu değişkenlerin doğrudan değerlerine erişilemez.
6.11.7 Değerlendirme
Sarkan işaretçiler ve çöp sorunları zaten tartışıldı.
uzunluk. Yığın yönetiminin sorunları Bölüm 6.11.8.3'te tartışılmaktadır.
İşaretçiler goto ile karşılaştırılmıştır. Goto ifadesi konuyu genişletiyor
Daha sonra yürütülebilecek ifadeler aralığı. İşaretçi değişkenleri aralığı genişletir
Bir değişken tarafından başvurulabilecek bellek hücrelerinin sayısı. Belki de en lanetlisi
İşaretçilerle ilgili açıklama Hoare (1973) tarafından yapılmıştır:
yüksek seviyeli diller, asla kurtulamayacağımız bir geri adım oldu.”
Öte yandan, bazı programlama türlerinde işaretçiler çok önemlidir.
uygulamalar. Örneğin, aygıt sürücülerini yazmak için işaretçiler gereklidir.
hangi belirli mutlak adreslere erişilmesi gerektiği.
Java ve C# referansları biraz esneklik sağlar ve
tehlikeler olmadan işaretçilerin yetenekleri. olup olmadığını görmek için kalır
programcılar, C ve C++ işaretçilerinin tüm gücünü
referansların daha fazla güvenliği. C# programlarının işaretçileri ne ölçüde kullandığı
bunun bir ölçüsü olacaktır.
6.11.8 İşaretçi ve Referans Türlerinin Uygulanması
Çoğu dilde, yığın yönetiminde işaretçiler kullanılır. aynısı doğrudur
Java ve C# referanslarının yanı sıra Smalltalk ve Ruby'deki değişkenler için
işaretçileri ve referansları ayrı ayrı ele alamayız. Önce kısaca anlatalım
işaretçilerin ve referansların dahili olarak nasıl temsil edildiği. sonra ikisini tartışırız
sarkan işaretçi sorununa olası çözümler. Son olarak, tarif ediyoruz
yığın yönetimi teknikleriyle ilgili büyük sorunlar.
6.1.8.1 İşaretçilerin ve Referansların Temsilleri
Çoğu büyük bilgisayarda, işaretçiler ve referanslar, içinde depolanan tek değerlerdir.
hafıza hücreleri. Ancak, Intel mikropro-
cessors, adreslerin iki bölümü vardır: bir segment ve bir ofset. Yani, işaretçiler ve
referanslar bu sistemlerde 16-bit hücre çiftleri olarak uygulanır.
bir adresin iki bölümünün her biri.
6.11.8.2 Sarkan İşaretçi Sorununun Çözümleri
Sarkan işaretçi sorununa önerilen birkaç çözüm vardır.
Bunlar arasında olan kaldırıldı olarak işaretler (1975 Lomet), burada her bir yığın, dinamik
değişken, kendisi bir işaretçi olan, mezar taşı adı verilen özel bir hücre içerir.
yığın dinamik değişken. Gerçek işaretçi değişkeni yalnızca mezar taşlarına işaret eder

Sayfa 319
298
Bölüm 6 Veri Tipleri
ve asla dinamik değişkenleri yığınlamak için. Yığın dinamik bir değişken serbest bırakıldığında
belirtilmişse, mezar taşı kalır ancak sıfır olarak ayarlanmıştır, bu da yığın-dinamik
değişken artık yok. Bu yaklaşım, bir işaretçinin hiç işaret etmesini önler
ayrılmış bir değişkene. Bir herhangi işaretçi bir değini, bu puan sıfıra
mezar taşı bir hata olarak algılanabilir.
Mezar taşları hem zaman hem de mekan açısından maliyetlidir. Çünkü mezar taşları
asla serbest bırakılmaz, depoları asla geri alınmaz. Bir yığına her erişim-
Bir mezar taşından geçen dinamik değişken, bir daha fazla yönlendirme seviyesi gerektirir,
çoğu bilgisayarda ek bir makine döngüsü gerektirir. Görünen o ki
daha popüler dillerin tasarımcılarından hiçbiri ek
bu ek maliyete değecek güvenlik, çünkü yaygın olarak kullanılan hiçbir dil kullanılmaz.
mezar taşları.
Mezar taşlarına bir alternatif, burada kullanılan kilitler ve anahtarlar yaklaşımıdır .
UW-Pascal'ın uygulanması (Fischer ve LeBlanc, 1977, 1980). Bunda
derleyici, işaretçi değerleri sıralı çiftler (anahtar, adres) olarak temsil edilir, burada
anahtar bir tamsayı değeridir. Yığın dinamik değişkenleri depo olarak temsil edilir.
değişken için yaş artı bir tamsayı kilit değeri depolayan bir başlık hücresi. Ne zaman
bir yığın dinamik değişken tahsis edilir, bir kilit değeri oluşturulur ve her ikisine de yerleştirilir
yığın dinamik değişkeninin kilit hücresinde ve işaretçinin anahtar hücresinde
çağrıda belirtilen new . Başvurusu kaldırılmış işaretçiye her erişim
işaretçinin anahtar değerini yığın-dinamikteki kilit değeriyle karşılaştırır
değişken. Eşleşirlerse erişim yasaldır; aksi takdirde erişim bir
çalışma hatası. İşaretçi değerinin diğer işaretçilere kopyaları kopyalanmalıdır.
anahtar değer. Bu nedenle, herhangi bir sayıda işaretçi belirli bir yığına başvurabilir.
dinamik değişken. Yığın dinamik bir değişken dislocated ile serbest bırakıldığında
poz , kilit değeri geçersiz bir kilit değerine temizlenir. Sonra, eğer bir işaretçi diğer
elden çıkarmada belirtilenden daha fazla referans alınırsa, adres değeri
yine de bozulmadan kalır, ancak anahtar değeri artık kilitle eşleşmeyecektir, bu nedenle erişim
izin verilmeyecektir.
Tabii ki, sarkan işaretçi sorununa en iyi çözüm,
yığın dinamik değişkenlerin programcıların elinden ayrılması. Eğer
programlar yığın dinamik değişkenlerini açıkça serbest bırakamaz,
sarkan işaretçiler. Bunu yapmak için, çalışma zamanı sistemi örtük olarak serbest bırakılmalıdır.
yığın dinamik değişkenler artık kullanışlı olmadıklarında. LISP sistemleri var
bunu hep yaptı. Hem Java hem de C#, bu yaklaşımı referans olarak kullanır.
değişkenler. C#'ın işaretçilerinin örtük serbest bırakma içermediğini hatırlayın.
6.11.8.3 Yığın Yönetimi
Yığın yönetimi çok karmaşık bir çalışma zamanı süreci olabilir. inceliyoruz
işlemi iki ayrı durumda gerçekleştirir: birinde tüm yığın depolamanın tahsis edildiği ve
tek boyutlu ve değişken boyutlu bölümlerin yer aldığı birimler halinde dağıtılır.
tahsis edilmiş ve tahsis edilmiştir. Serbest bırakma için, yalnızca örtük olarak tartıştığımızı unutmayın.
yaklaşımlar. Tartışmamız kısa ve kapsamlı olmaktan uzak olacak, çünkü bir
Bu süreçlerin ve bunlarla ilişkili sorunların kapsamlı bir analizi öyle değildir.
bir uygulama sorunu olduğu için bir dil tasarımı sorunudur.

Sayfa 320
6.11 İşaretçi ve Referans Türleri 299
Tek Boyutlu Hücreler En basit durum, tüm ayırma ve
tek boyutlu hücrelerden oluşur. Her hücre zaten uyumlu olduğunda daha da basitleşir.
bir işaretçi içerir. Bu, birçok LISP uygulamasının senaryosudur, burada
Dinamik depolama tahsisi sorunları ilk olarak büyük bir
ölçek. Tüm LISP programları ve çoğu LISP verisi, bağlantılı listelerdeki hücrelerden oluşur.
Tek boyutlu bir ayırma yığınında, kullanılabilir tüm hücreler birbirine bağlanır
hücrelerdeki işaretçileri kullanarak, kullanılabilir alanın bir listesini oluşturur. Tahsis bir
olduklarında bu listeden gerekli sayıda hücreyi almak basit bir meseledir.
ihtiyaç vardır. Serbest bırakma çok daha karmaşık bir süreçtir. Yığın dinamik
değişken birden fazla işaretçi ile gösterilebilir, bu da
değişkenin program için artık yararlı olmadığını belirleyin. Basitçe çünkü
bir işaretçinin bir hücreyle bağlantısının kesilmesi onu açıkça çöp yapmaz;
hala hücreye işaret eden birkaç başka işaretçi olabilir.
LISP'de, programlarda en sık yapılan işlemlerden birkaçı koleksiyon oluşturur.
artık program tarafından erişilemeyen ve bu nedenle
serbest bırakılabilir (mevcut alan listesine geri koyun). Temel biri
LISP'nin tasarım hedefleri, kullanılmayan hücrelerin ıslahının
programcının görevi değil, çalışma zamanı sisteminin görevi olmalıdır. Bu hedef
LISP uygulayıcılarını temel tasarım sorusuyla bıraktı: Ne zaman
delokasyon gerçekleştirilecek mi?
Çöp toplama için birkaç farklı yaklaşım vardır. en çok iki
yaygın geleneksel teknikler, bazı yönlerden zıt süreçlerdir. Bunlar
ıslahın artımlı olduğu ve yapıldığı adlandırılmış referans sayaçları
erişilemeyen hücreler oluşturulduğunda ve ıslahın yapıldığı işaretleme-süpürme
yalnızca kullanılabilir alan listesi boşaldığında oluşur. Bu iki yöntem
bazen sırasıyla istekli yaklaşım ve tembel yaklaşım olarak adlandırılır.
Bu iki yaklaşımın birçok varyasyonu geliştirilmiştir. Bu bölümde,
ancak, yalnızca temel süreçleri tartışıyoruz.
Depo ıslahının referans sayaç yöntemi amacına ulaşır
her hücrede işaretçilerin sayısını depolayan bir sayaç bulundurarak
şu anda hücreyi gösteriyorlar. için azaltma işlemine gömülü
bir işaretçi hücreden ayrıldığında ortaya çıkan referans sayaçları,
sıfır değeri için bir kontroldür. Referans sayacı sıfıra ulaşırsa, bunun anlamı şudur:
hiçbir program işaretçisi hücreye işaret etmiyor ve bu nedenle çöp oldu
ve kullanılabilir alan listesine döndürülebilir.
Referans sayacı yöntemiyle ilgili üç farklı sorun vardır. Öncelikle,
depolama hücreleri nispeten küçükse, sayaçlar için gerekli alan önemlidir.
olamaz. İkincisi, sayacı korumak için açıkça bir miktar yürütme süresi gereklidir.
değerler. Bir işaretçi değeri her değiştirildiğinde, işaret ettiği hücre
sayacı azaltılmış olmalı ve şimdi işaret ettiği hücre
sayacını artırın. LISP gibi bir dilde, neredeyse her
eylem, toplamın önemli bir kısmı olabilen işaretçileri değiştirmeyi içerir.
bir programın yürütme süresi. Elbette, işaretçi değişiklikleri çok sık değilse,
bu sorun değil. Referans sayaçlarının verimsizliğinden bazıları şunlar olabilir:
kaçınan ertelenmiş referans sayımı adlı bir yaklaşımla ortadan kaldırılmıştır.
bazı işaretçiler için referans sayaçları. Üçüncü sorun, komplikasyonların

Sayfa 321
300
Bölüm 6 Veri Tipleri
bir hücre topluluğu dairesel olarak bağlandığında ortaya çıkar. Buradaki sorun şu ki
dairesel listedeki her hücrenin en az 1 referans sayaç değeri vardır, bu
toplanmasını ve kullanılabilir alan listesine geri yerleştirilmesini engeller. A
bu sorunun çözümü Friedman ve Wise'da (1979) bulunabilir.
Referans sayacı yaklaşımının avantajı, özünde
artımlı. Eylemleri, uygulamanınkilerle karıştırılmıştır, bu nedenle asla
uygulamanın yürütülmesinde önemli gecikmelere neden olur.
Çöp toplamanın orijinal işaretleme-süpürme süreci şu şekilde çalışır:
Çalışma zamanı sistemi, depolama hücrelerini istendiği gibi tahsis eder ve noktaların bağlantısını keser.
depolama ıslahına bakılmaksızın, gerektiğinde hücrelerden
birikecek çöp), mevcut tüm hücreleri tahsis edene kadar. Bu noktada, bir
içinde yüzen tüm çöpleri toplamak için işaretleme-süpürme işlemi başlatılır.
yığın. İşlemi kolaylaştırmak için, her yığın hücresinin fazladan bir gösterge biti veya
toplama algoritması tarafından kullanılan alan.
İşaretleme-süpürme süreci üç farklı aşamadan oluşur. İlk olarak, tüm hücreler
yığın, göstergelerini çöp olduklarını gösterecek şekilde ayarlamıştır. Bu, elbette,
sadece bazı hücreler için doğru bir varsayım. İşaret olarak adlandırılan ikinci kısım-
aşaması, en zorudur. Programdaki her işaretçi,
yığın ve erişilebilir tüm hücreler çöp değil olarak işaretlenir. Bundan sonra üçüncü
süpürme aşaması olarak adlandırılan aşama yürütülür: Yığındaki henüz silinmemiş tüm hücreler
hala kullanılmakta olarak özellikle işaretlenenler, kullanılabilir alan listesine döndürülür.
Curl olan hücreleri işaretlemek için kullanılan algoritmaların lezzetini göstermek için.
kullanımdayken, bir işaretleme algoritmasının aşağıdaki basit sürümünü sunuyoruz.
Tüm yığın dinamik değişkenlerinin veya yığın hücrelerinin bir bilgiden oluştuğunu varsayıyoruz.
bölüm; işareti, adında bir kısmı işaretleyici ; ve llink adlı iki işaretçi
ve rlink . Bu hücreler, en fazla iki ile yönlendirilmiş grafikler oluşturmak için kullanılır.
herhangi bir düğümden önde gelen kenarlar. İşaretleme algoritması tüm kapsama alanını kat eder
bulunan tüm hücreleri işaretleyen grafik ağaçları. Diğer grafik geçişleri gibi,
işaretleme algoritması özyinelemeyi kullanır.
için her işaretçi r do
işaret(r)
void mark( void * ptr) {
eğer (ptr != 0)
if (*ptr.marker işaretli değil) {
*ptr.marker'ı ayarla
işaret(*ptr.llink)
işaret(*ptr.rlink)
}
}
Verilen bir grafik üzerinde bu prosedürün eylemlerinin bir örneği aşağıdaki şekilde gösterilmiştir:
Şekil 6.11. Bu basit işaretleme algoritması, çok fazla depolama alanı gerektirir.
özyinelemeyi desteklemek için yığın alanı). İlave gerektirmeyen bir markalama işlemi
Ulusal yığın uzayı Schorr ve Waite (1967) tarafından geliştirilmiştir. onların yöntemi

Sayfa 322
6.11 İşaretçi ve Referans Tipleri 301
bağlantılı yapıların izini sürerken işaretçileri tersine çevirir. Sonra, bir listenin sonu
ulaşıldığında, süreç işaretçileri yapının dışına geri takip edebilir.
Mark-sweep'in orijinal versiyonundaki en ciddi sorun şuydu:
çok seyrek yapıldı - yalnızca bir program tümünü veya neredeyse tamamını kullandığında
yığın depolama. Bu durumda işaret-süpürme çok zaman alır, çünkü
hücrelerin çoğu izlenmeli ve şu anda kullanılmakta olarak işaretlenmelidir. Bu neden olur
başvurunun ilerlemesinde önemli bir gecikme. Ayrıca, süreç
kullanılabilirler listesine yerleştirilebilecek yalnızca az sayıda hücre verebilir.
mümkün alan. Bu sorun çeşitli iyileştirmelerle giderildi. İçin
örneğin, artımlı işaretleme-süpürme çöp toplama işlemi daha sık gerçekleşir,
bellek tükenmeden çok önce, süreci daha etkili hale getirir
geri kazanılan depolama miktarı. Ayrıca, her çalıştırma için gereken süre
sürecin süresi açıkça daha kısadır, bu nedenle uygulama yürütmedeki gecikmeyi azaltır.
tion. Diğer bir alternatif ise işaret süpürme işlemini parçalar üzerinde gerçekleştirmektir.
farklı zamanlarda uygulamayla ilişkili tüm bellekten daha fazla. Bu
artımlı işaretleme-süpürme ile aynı türde iyileştirmeler sağlar.
Hem işaretleme tarama yöntemi hem de süreçler için işaretleme algoritmaları
referans sayaç yönteminin gerektirdiği kullanım ile daha verimli hale getirilebilir
Suzuki (1982) tarafından açıklanan işaretçi döndürme ve kaydırma işlemleri.
Değişken boyutlu hücreler değişken boyutlu hücreleri olan bir yığın yönetme 9 olan allo
cated, tek boyutlu hücreler için bir tane yönetmenin tüm zorluklarına sahiptir, ancak aynı zamanda
ek sorunlar. Ne yazık ki, çoğu kişi değişken boyutlu hücrelere ihtiyaç duyar.
9. Hücrelerin boyutları değişkendir çünkü bunlar, değişkenlerin değerlerini depolayan soyut hücrelerdir.
türleri ne olursa olsun. Ayrıca, bir değişken yapılandırılmış bir tür olabilir.
Şekil 6.11
Bir örnek
işaretleme eylemleri
algoritma
x
x
x
x
x
x
x
x
x
x
x
1
2
3
4
5
6
8
9
10
12
7
11
r
Kesikli çizgiler, node_marking sırasını gösterir

Sayfa 323
302
Bölüm 6 Veri Tipleri
Programlama dilleri. Değişken boyutlu hücrenin ortaya çıkardığı ek sorunlar
yönetimi kullanılan yönteme bağlıdır. İşaretleme-süpürme kullanılıyorsa, aşağıdakiler
ek sorunlar oluşur:
• Bunu belirtmek için yığındaki tüm hücrelerin göstergelerinin ilk ayarı
onlar çöp zordur. Hücreler farklı boyutlarda olduğu için tarama
onlar bir problem. Bir çözüm, her hücrenin hücre boyutuna sahip olmasını istemektir.
onun ilk alanı. Ardından, biraz daha uzun sürse de tarama yapılabilir.
uzay ve sabit boyutlu hücreler için muadilinden biraz daha fazla zaman.
• İşaretleme süreci önemsizdir. Bir zincir bir noktadan nasıl takip edilebilir?
işaretçi için işaretçi için önceden tanımlanmış bir konum yoksa işaretçi
hücre? Hiç işaretçi içermeyen hücreler de bir sorundur. Ekleme
tarafından arka planda tutulan her hücreye bir dahili işaretçi
çalışma zamanı sistemi, çalışacaktır. Ancak, bu arka plan bakımı
işleme, maliyete hem alan hem de yürütme süresi ek yükü ekler.
programı çalıştırıyor.
• Kullanılabilir alan listesinin tutulması başka bir ek yük kaynağıdır. bu
liste, tüm kullanılabilir alandan oluşan tek bir hücreyle başlayabilir. İstekler
segmentler için bu bloğun boyutunu küçültün. Geri kazanılan hücreler eklendi
listeye. Sorun şu ki, çok geçmeden liste uzun bir liste haline gelir.
çeşitli büyüklükteki bölümler veya bloklar. Bu, tahsisi yavaşlatır çünkü istekler
listenin yeterince büyük bloklar için aranmasına neden olur. Sonunda,
liste, büyük olmayan çok sayıda çok küçük bloktan oluşabilir.
çoğu istek için yeterli. Bu noktada, bitişik blokların olması gerekebilir.
daha büyük bloklara bölündü. İlk yeterince büyük olanı kullanmanın alternatifleri
listedeki blok aramayı kısaltabilir ancak listenin sıralanmasını gerektirebilir
blok boyutuna göre. Her iki durumda da, listeyi sürdürmek ek yüktür.
Referans sayaçları kullanılırsa, ilk iki problemden kaçınılır, ancak
kullanılabilir alan listesi bakım sorunu devam ediyor.
Bellek yönetimi sorunlarına ilişkin kapsamlı bir çalışma için, bkz. Wilson
(2005).
6.12 Tip Kontrolü
Tip denetimi tartışması için, işlenenler ve operatörler kavramı
alt programları ve atama ifadelerini içerecek şekilde genelleştirilmiştir. alt pro-
gram, işlenenleri parametreleri olan operatörler olarak düşünülecektir.
Atama sembolü, hedefi ile ikili bir operatör olarak düşünülecektir.
değişken ve ifadesi işlenenlerdir.
Tip kontrolü , bir işlemin işlenenlerinin doğruluğunu sağlama faaliyetidir.
tor uyumlu türlerdedir. Bir uyumlu tipi ya yasal olandır
operatör veya dil kuralları uyarınca dolaylı olarak dönüştürülmesine izin verilir
derleyici tarafından oluşturulan kod (veya yorumlayıcı) yasal bir türe dönüştürülür. Bu otomatik
dönüştürmeye zorlama denir . Örneğin, bir int değişkeni ve bir kayan nokta

Sayfa 324
6.13 Güçlü Yazma 303
Java'da değişken eklenir, int değişkeninin değeri yüzmeye zorlanır
ve kayan nokta eklemesi yapılır.
Bir tür hatası , bir operatörün bir uygulamanın işlenenine uygulanmasıdır.
uygun tip. Örneğin, C'nin orijinal sürümünde, bir int değeri
kayan değer bekleyen bir işleve iletilirse , bir tür hatası oluşur
(çünkü o dilin derleyicileri parametre türlerini kontrol etmedi).
Bir dilde tüm değişkenlerin türlere bağlanması statik ise, check- yazın.
ing neredeyse her zaman statik olarak yapılabilir. Dinamik tür bağlama, tür gerektirir
dinamik tip denetimi adı verilen çalışma zamanında denetim .
JavaScript ve PHP gibi bazı diller dinamik olmaları nedeniyle
tür bağlama, yalnızca dinamik tür denetimine izin verir. Hataları tespit etmek daha iyidir
derleme zamanında, çalışma zamanından daha erken, çünkü daha önceki düzeltme genellikle daha az
pahalı. Statik kontrolün cezası programcı esnekliğinin azalmasıdır. Daha az
kısayollar ve püf noktaları mümkündür. Ancak bu tür teknikler artık genel olarak
hataya açık olduğu ve okunabilirliğe zarar verdiği kabul edilmiştir.
Bir dil, bir bellek hücresinin
yürütme sırasında farklı zamanlarda farklı türlerdeki değerleri depolar. Böyle bir hafıza
hücreler Ada varyant kayıtları, C ve C++ birleşimleri ve dis-
ML, Haskell ve F# ile suçlanan sendikalar. Bu durumlarda, tip denetimi, eğer
yapılır, dinamik olmalı ve türü korumak için çalışma zamanı sistemini gerektirir
bu tür bellek hücrelerinin mevcut değerinin. Yani, tüm değişkenler olsa bile
C++ gibi dillerdeki türlere statik olarak bağlıdır, tüm tür hataları
statik tip kontrolü ile tespit edildi.
6.13 Güçlü Yazma
Sözde dil tasarımında öne çıkan fikirlerden biri
1970'lerin yapılandırılmış programlama devrimi güçlü tiplemeydi . Güçlü
Yazma, yaygın olarak çok değerli bir dil özelliği olarak kabul edilmektedir.
tik. Ne yazık ki, genellikle gevşek bir şekilde tanımlanır ve genellikle bilgi işlemde kullanılır.
edebiyat hiç tanımlanmadan.
Tür hataları her zaman varsa , bir programlama dili güçlü bir şekilde yazılmıştır.
saptanmış. Bu, tüm işlenen türlerinin ya da belirlenebilmesini gerektirir.
derleme zamanında veya çalışma zamanında. Güçlü tiplemenin önemi, yeteneğinde yatmaktadır.
tür hatalarına neden olan tüm değişken yanlış kullanımlarını tespit etmek için. Güçlü bir şekilde yazılmış
dil ayrıca, çalışma zamanında yanlış türdeki kullanımların algılanmasına da izin verir.
birden fazla türün değerlerini depolayabilen değişkenlerdeki değerler.
Ada neredeyse güçlü bir şekilde yazılmıştır. Sadece neredeyse güçlü bir şekilde yazılmıştır çünkü
programcıların özellikle talep ederek tip kontrol kurallarını ihlal etmelerine izin verir.
belirli bir tür dönüştürme için bu tür denetimi askıya alınır. Bu
tür denetiminin geçici olarak askıya alınması, yalnızca bir örnekleme yapıldığında yapılabilir.
genel işlevin Unchecked_Conversion çağrılır. Bu tür işlevler
herhangi bir alt tip çifti için somutlaştırılabilir. Biri parametresinin bir değerini alır
yazın ve parametrenin geçerli değeri olan bit dizesini döndürür. gerçek yok
dönüşüm gerçekleşir; sadece bir değişkenin değerini çıkarmanın bir yoludur

Sayfa 325
304
Bölüm 6 Veri Tipleri
bir türden ve onu farklı bir türdenmiş gibi kullanmaktır. Bu tür konver-
sion bazen dönüştürmeyen döküm olarak adlandırılır . İşaretlenmemiş dönüşümler olabilir
kullanıcı tanımlı depolama tahsisi ve serbest bırakma işlemleri için kullanışlıdır.
adresler tamsayı olarak işlenir ancak işaretçiler olarak kullanılmalıdır. Çünkü hayır
Kontrol Unchecked_Conversion'da yapılır , bu programcının cevabıdır.
ondan elde edilen bir değerin kullanımının anlamlı olmasını sağlama yeteneği.
Her ikisi de birliği içerdiğinden, C ve C++ kesin olarak yazılan diller değildir
tip kontrolü yapılmayan tipler.
Bazı işlev parametrelerinin türleri olsa da, ML güçlü bir şekilde yazılmıştır.
derleme zamanında bilinmeyebilir. F# kesinlikle yazılmıştır.
Java ve C#, C++'a dayalı olmalarına rağmen, güçlü bir şekilde
Ada ile aynı anlamda. Türler, bir türle sonuçlanabilecek şekilde açıkça yayınlanabilir.
hata. Ancak, tür hatalarının tespit edilmemesinin kesin bir yolu yoktur.
Bir dilin zorlama kuralları, dilin değeri üzerinde önemli bir etkiye sahiptir.
tip denetimi. Örneğin, ifadeler Java'da güçlü bir şekilde yazılır. Ancak,
bir kayan nokta işleneni ve bir tamsayı işleneni olan bir aritmetik işleç
ve yasaldır. Tamsayı işleneninin değeri kayan noktaya zorlanır ve
kayan nokta işlemi gerçekleşir. Bu genellikle tarafından amaçlanan şeydir
programcı. Bununla birlikte, zorlama aynı zamanda faydalardan birinin kaybolmasına da neden olur.
güçlü yazma—hata algılama. Örneğin, bir programın şu özelliklere sahip olduğunu varsayalım:
int değişkenleri a ve b ve kayan değişken d . Şimdi, eğer bir programcı demek istiyorsa
yazmak için , a + b , ama yanlış yazılmış bir + d , hata tespit olmaz
derleyici tarafından. Değeri a basitçe coerced olacağını şamandıra . Böylece
güçlü tiplemenin değeri zorlama ile zayıflatılır. Çok fazla olan diller
C ve C++ gibi zorlama, çok az zorlamaya sahip olanlardan daha az güvenilirdir.
Ada gibi ve ML ve F# gibi zorlama olmayanlar. Java ve C# yarısı var
C++ kadar çok atama türü zorlaması vardır, bu nedenle hata algılamaları daha iyidir
C++'dan daha iyidir, ancak yine de ML ve F# kadar etkili değildir. bu
zorlama konusu Bölüm 7'de ayrıntılı olarak incelenmektedir.
6.14 Tip Eşdeğerliği
Tip uyumluluğu fikri, tip denetimi konusu gündeme geldiğinde tanımlandı.
tanıtıldı. Uyumluluk kuralları, işlenen türlerini belirler.
operatörlerin her biri için kabul edilebilir ve böylece olası tip hatalarını belirtin
dilin. 10 Kurallara uyumluluk denir çünkü bazı durumlarda
bir işlenenin türü, derleyici veya çalışma zamanı tarafından örtük olarak dönüştürülebilir
Operatör tarafından kabul edilebilir hale getirmek için sistem.
Tür uyumluluğu kuralları, önceden tanımlanmış skaler için basit ve katıdır.
türleri. Ancak, diziler ve kayıtlar gibi yapılandırılmış türlerde ve
10. Tip uyumluluğu aynı zamanda bir dizideki gerçek parametreler arasındaki ilişkide de bir sorundur.
alt program çağrısı ve alt program tanımının resmi parametreleri. Bu konu dis-
Bölüm 9'da tartışıldı.

Sayfa 326
6.14 Tip Denkliği 305
bazı kullanıcı tanımlı türler, kurallar daha karmaşıktır. Bu tür zorlamalar
nadirdir, bu nedenle sorun tür uyumluluğu değil, tür denkliğidir. yani, iki
bir ifadede bir tür işlenen değiştirilirse türler eşdeğerdir
zorlama olmadan diğer türden biri için. Tür denkliği katı bir formdur
tür uyumluluğu—zorlama olmadan uyumluluk. Buradaki asıl mesele
tür denkliğinin nasıl tanımlandığıdır.
Bir dilin tür denklik kurallarının tasarımı önemlidir,
çünkü veri türlerinin tasarımını ve sağlanan işlemleri etkiler.
Bu türlerin değerleri için. Burada tartışılan türlerle birlikte, çok az ön-
tanımlanmış işlemler Belki de iki değişkenin en önemli sonucu
eşdeğer türlerden biri, birinin değerinin diğerine atanabilmesidir.
Tip denkliğini tanımlamaya yönelik iki yaklaşım vardır: isim tipi denkliği
lens ve yapı tipi denkliği. Ad türü eşdeğerliği , iki
değişkenler, aynı bildirimde tanımlanmışlarsa eşdeğer türlere sahiptir.
veya aynı tür adını kullanan bildirimlerde. Yapı tipi denkliği
türleri aynıysa, iki değişkenin eşdeğer türlere sahip olduğu anlamına gelir.
yapılar. Bu iki yaklaşımın bazı varyasyonları vardır ve birçok alan
göstergeler bunların kombinasyonlarını kullanır.
Ad türü denkliğinin uygulanması kolaydır ancak daha kısıtlayıcıdır. Altında
katı bir yorum, türü tam sayıların bir alt aralığı olan bir değişken
bir tamsayı türü değişkene eşdeğer olamaz. Örneğin, Ada'nın kullandığını varsayalım.
katı ad türü denkliği için aşağıdaki Ada kodunu göz önünde bulundurun:
tip Indextype olan 1..100;
say : Tamsayı;
dizin : Dizin türü;
Değişkenlerin sayısı ve indeksi türleri eşdeğer olmaz; saymak
tahsis edilemeyen endeksi ya da tam tersi.
Ad türü eşdeğerliği ile ilgili başka bir sorun, yapılandırılmış veya
kullanıcı tanımlı tip, parametreler aracılığıyla alt programlar arasında geçirilir. böyle bir
type global olarak yalnızca bir kez tanımlanmalıdır. Bir alt program türü belirtemez
yerel terimlerle bu tür resmi parametrelerin orjinalinde böyleydi
Pascal'ın versiyonu.
Ad türü eşdeğerliğini kullanmak için tüm türlerin adlarının olması gerektiğini unutmayın. Çoğu
diller, kullanıcıların anonim türleri tanımlamasına izin verir;
isimler. Bir dilin ad türü eşdeğerliğini kullanması için, bu türlerin örtük olarak
derleyici tarafından dahili adlar verilebilir.
Yapı tipi denkliği, isim tipi denkliğinden daha esnektir, ancak
uygulanması daha zordur. Ad türü eşdeğerliği altında, yalnızca iki
tür adları denkliği belirlemek için karşılaştırılmalıdır. yapı tipi altında
ancak eşdeğerlik, iki türün tüm yapılarının karşılaştırılması gerekir.
Bu karşılaştırma her zaman basit değildir. (Şunu ifade eden bir veri yapısı düşünün:
bağlantılı bir liste gibi kendi türü.) Başka sorular da ortaya çıkabilir. Örneğin,
aynı yapıya sahiplerse eşdeğer olan iki kayıt (veya yapı ) türüdür, ancak
farklı alan adları? Fortran'da iki tek boyutlu dizi türü var mı yoksa

Sayfa 327
306
Bölüm 6 Veri Tipleri
Aynı öğe türüne sahiplerse ancak alt simgeye sahiplerse Ada programı eşdeğeri
0..10 ve 1..11 aralıkları ? Varsa, iki numaralandırma türü eşdeğer midir?
aynı sayıda bileşen var, ancak değişmezleri farklı mı yazıyorsunuz?
Yapı tipi denkliği ile ilgili bir diğer zorluk, farklılaşmaya izin vermemesidir.
aynı yapıya sahip türler arasında ferenti eden. Örneğin, şunu düşünün:
Ada benzeri bildirimleri izleyerek:
tip Celsius = Float;
Fahrenhayt = Şamandıra;
Bu iki türün değişken türleri, aşağıda eşdeğer olarak kabul edilir.
ifadelerde karıştırılmalarına izin veren yapı türü eşdeğerliği,
türün belirttiği fark göz önüne alındığında, bu durumda kesinlikle istenmeyen
isimler. Genel olarak, farklı adlara sahip türlerin soyutlamaları olması muhtemeldir.
farklı kategorilerdeki problem değerleri ve eşdeğer olarak kabul edilmemelidir.
Ada, kısıtlayıcı bir ad türü denkliği biçimi kullanır, ancak iki tür
ile ilişkili sorunlardan kaçınan yapılar, alt türler ve türetilmiş türler
isim türü denkliği Bir türetilmiş tip bir temel alan yeni bir tür
sahip olmasına rağmen, eşdeğer olmadığı önceden tanımlanmış tür
özdeş yapı. Türetilmiş türler, üst türlerinin tüm özelliklerini devralır.
Aşağıdaki örneği göz önünde bulundurun:
türü santigrat yeni Şamandıra;
tipi Fahrenheit yeni Float;
Bu iki türetilmiş türün değişken türleri eşdeğer değildir, ancak
yapıları aynıdır. Ayrıca, her iki türün değişkenleri de tür değildir.
diğer herhangi bir kayan nokta türüyle eşdeğerdir. Harfler muaftır
kural. 3.0 gibi bir hazır bilgi , evrensel gerçek türüne sahiptir ve türe eşdeğerdir.
herhangi bir kayan nokta türü. Türetilmiş türler, aynı zamanda aralık kısıtlamalarını da içerebilir.
ebeveyn türü, yine de ebeveynin tüm işlemlerini devralırken.
Bir Ada alt türü , mevcut bir türün muhtemelen menzil kısıtlamalı bir versiyonudur.
Bir alt tür, üst türüyle tür eşdeğeridir. Örneğin, şunu düşünün:
aşağıdaki beyan:
alt tür Small_type: Tamsayı aralığı 0..99;
Tipi Small_type tip eşdeğerdir Tamsayı .
Ada'nın türetilmiş türlerinin, Ada'nın alt aralık türlerinden çok farklı olduğuna dikkat edin.
Örneğin, aşağıdaki tür bildirimlerini göz önünde bulundurun:
tür Derived_Small_Int yeni Tamsayı aralığıdır 1..100;
alt tip Subrange_Small_Int olan tamsayı aralığı 1..100;
Her iki tür, Değişkenler Derived_Small_Int ve Subrange_Small_Int ,
aynı yasal değerler aralığına sahiptir ve her ikisi de Tamsayı işlemlerini devralır .

Sayfa 328
6.14 Tip Denkliği 307
Ancak, Derived_Small_Int türündeki değişkenler hiçbiriyle uyumlu değildir.
Tamsayı türü. Öte yandan, Subrange_Small_Int türündeki değişkenler
Tamsayı türü ve herhangi bir alt türün değişkenleri ve sabitleri ile uyumludur
arasında Tamsayı .
Ada kısıtlamasız dizi tipindeki değişkenler için, yapı tipi eşdeğeri
lens kullanılır. Örneğin, aşağıdaki tür bildirimini göz önünde bulundurun ve iki
nesne bildirimleri:
tip vektör dizi (Tamsayı aralık <>) arasında bir tamsayı;
Vector_1: Vektör (1..10);
Vector_2: Vektör (11..20);
Bu iki nesnenin türleri, farklı olmalarına rağmen eşdeğerdir.
ent adları ve farklı alt simge aralıkları, çünkü kısıtlanmamış nesneler için
dizi türleri, ad türü eşdeğerliği yerine yapı türü eşdeğerliği
Kullanılmış. Çünkü her iki türün de 10 öğesi vardır ve her ikisinin öğeleri de türdendir.
Tamsayı , tür eşdeğerleridir.
Ada, kısıtlı anonim türler için oldukça kısıtlayıcı bir
isim türü denkliği Aşağıdaki Ada'nın kısıtlı bildirimlerini göz önünde bulundurun:
anonim türler:
C: dizi (1.10) arasında bir tamsayı;
Bu durumda A , derleyici tarafından atanan anonim ancak benzersiz bir türe sahiptir ve
programda kullanılamaz. biz de olsaydık
B: dizisi (1.10) arasında bir tamsayı;
A ve B , anonim ancak farklı ve eşdeğer olmayan türlerde olacaktır.
yapısal olarak aynıdırlar. çoklu deklarasyon
C, D: dizisi (1.10) arasında bir tamsayı;
eşdeğer olmayan biri C ve diğeri D için olmak üzere iki anonim tür oluşturur .
Bu beyan aslında aşağıdaki iki beyanmış gibi ele alınır:
C: dizi (1.10) arasında bir tamsayı;
D: dizisi (1.10) arasında bir tamsayı;
Ada'nın ad türü eşdeğerlik biçiminin,
Bu bölümün başında tanımlanan ad türü eşdeğerliği. Eğer biz
onun yerine yazmıştı
tip List_10 dizisidir (1.10) arasında bir tamsayı;
C, D : Liste_10;
o zaman C ve D türleri eşdeğer olacaktır.

Sayfa 329
308
Bölüm 6 Veri Tipleri
Ad türü eşdeğerliği Ada için iyi sonuç verir, çünkü kısmen
anonim diziler, tür adlarına sahip olmalıdır (ve anonim türler
derleyici tarafından verilen dahili adlar).
Ada için tür eşdeğerlik kuralları, diller için olanlardan daha katıdır
türler arasında birçok zorlamaya sahip olan. Örneğin, bir dizinin iki işleneni
Java'daki ekleme operatörü, hemen hemen her türlü sayısal tür kombinasyonuna sahip olabilir
dilde. İşlenenlerden biri basitçe türüne zorlanacak
diğeri. Ancak Ada'da, bir aritmetiğin işlenenlerinin zorlaması yoktur.
Şebeke.
C, hem ad hem de yapı türü eşdeğerliğini kullanır. Her yapı , enum ,
ve sendika bildirimi, diğerlerine eşdeğer olmayan yeni bir tür oluşturur.
tip. Bu nedenle, yapı, numaralandırma ve birleşim için ad türü eşdeğerliği kullanılır.
türleri. Diğer skaler olmayan türler, yapı türü eşdeğerliğini kullanır. dizi türleri
aynı tür bileşenlere sahiplerse eşdeğerdir. Ayrıca, bir dizi türünün bir
sabit boyut, aynı sabit boyuta sahip diğer dizilere eşdeğerdir
veya sabit bir boyutu olmayanlarla. O Not typedef C ve C ++ yapar
yeni bir tür tanıtmayın; sadece mevcut bir tip için yeni bir isim tanımlar.
Bu nedenle, typedef ile tanımlanan herhangi bir tür , üst türüne eşdeğerdir. Bir
yapılar, numaralandırmalar ve
sendikalar, iki yapının, numaralandırmanın veya birliğin farklı şekillerde tanımlanmasıdır.
dosyalar, bu durumda yapısal tip eşdeğerliği kullanılır. Bu boşlukta bir boşluk
yapıların, numaralandırmaların,
ve farklı dosyalarda tanımlanan birlikler.
C++, tanımlanan yapılar ve birleşimler için bir istisna olmaması dışında C gibidir.
farklı dosyalarda.
Kullanıcıların türleri tanımlamasına ve adlandırmasına izin vermeyen dillerde, örneğin
Fortran ve COBOL, isim denkliği açıkça kullanılamaz.
Java ve C++ gibi nesne yönelimli diller başka tür bir tür getirir
onlarla uyumluluk sorunu. Sorun nesne uyumluluğu ve onun ilişkisi-
Bölüm 12'de tartışılan miras hiyerarşisine gönderir.
İfadelerdeki tür uyumluluğu Bölüm 7'de tartışılmaktadır; tip uyumluluğu
alt program parametreleri için yetenek Bölüm 9'da tartışılmaktadır.
6.15 Teori ve Veri Tipleri
Tip teorisi, matematik, mantık, bilgisayar bilimlerinde geniş bir çalışma alanıdır.
ve felsefe. 1900'lerin başında matematikte başladı ve daha sonra
mantıkta standart bir araçtır. Tip teorisinin herhangi bir genel tartışması zorunlu olarak
karmaşık, uzun ve oldukça soyut. Bilgisayar bilimleriyle sınırlı olduğunda bile
Tip teorisi, yazılan lambda gibi çok çeşitli ve karmaşık konuları içerir.
kalkülüs, birleştiriciler, sınırlı nicelemenin metateorisi, varoluşsal
türleri ve yüksek dereceli polimorfizm. Bütün bu konuların çok ötesinde
bu kitabın kapsamı.
Bilgisayar biliminde tip teorisinin iki dalı vardır: pratik ve
Öz. Pratik dal, ticari veri türleri ile ilgilidir.

Sayfa 330
6.15 Teori ve Veri Tipleri 309
Programlama dilleri; soyut dal öncelikle yazılanlara odaklanır
teorik bilgisayar bilimleri tarafından kapsamlı bir araştırma alanı olan lambda hesabı
son yarım yüzyılda entists. Bu bölüm kısa bir açıklama ile sınırlıdır.
veri tiplerinin altında yatan bazı matematiksel formalizmlerin
Programlama dilleri.
Bir veri türü, bir değerler kümesini ve bunlar üzerinde bir işlemler koleksiyonunu tanımlar.
değerler. Bir tür sistemi, bir dizi tür ve bunların kullanımlarını yöneten kurallardır.
programlar. Açıkçası, yazılan her programlama dili bir tür sistemi tanımlar.
Tem. Bir programlama dilinin tip sisteminin biçimsel modeli,
tür kurallarını tanımlayan bir dizi tür ve bir işlevler koleksiyonundan oluşur.
Herhangi bir ifadenin türünü belirlemek için kullanılan dil. Resmi bir
Bir tür sisteminin kurallarını tanımlayan sistem, öznitelik dilbilgisi, giriştir.
3. Bölümde yapılmıştır.
Dilbilgilerini ilişkilendirmek için alternatif bir model, bir tür haritası ve bir sütun kullanır.
türü belirten dilbilgisi kurallarıyla ilişkili olmayan işlevlerin listesi
tüzük. Bir tür haritası, düz anlam için kullanılan bir programın durumuna benzer.
her birinin ilk elemanı olan bir dizi sıralı çiftten oluşan semantik
çifti bir değişkenin adı ve ikinci öğe de tipidir. Bir tür haritası
programdaki tür bildirimleri kullanılarak oluşturulur. Statik bir şekilde yazılmış
dil, tür haritasının yalnızca derleme sırasında korunması gerekir, ancak
program derleyici tarafından analiz edildiğinde değişir. Herhangi bir tip kontrolü ise
dinamik olarak yapıldığında, yürütme sırasında tür haritası korunmalıdır. bu
Bir derleme sistemindeki tip haritasının somut versiyonu sembol tablosudur,
öncelikle sözcük ve sözdizimi çözümleyicileri tarafından oluşturulur. Dinamik türler bazı-
zamanlar, değerlere veya nesnelere eklenen etiketlerle korunur.
Daha önce belirtildiği gibi, bir veri türü, bir veri türünde olmasına rağmen bir değerler kümesidir.
elemanlar genellikle sıralanır. Örneğin, tüm sıralı türlerdeki öğeler
sipariş edilir. Bu farklılığa rağmen, veri türleri üzerinde küme işlemleri kullanılabilir.
yeni veri türlerini tanımlar. Programlama dillerinin yapılandırılmış veri türleri
tür operatörleri veya küme işlemlerine karşılık gelen oluşturucular tarafından tanımlanır.
Bu küme işlemleri/tipi oluşturucuları aşağıda kısaca tanıtılmaktadır.
paragraflar.
Sonlu bir eşleme, sonlu bir değerler kümesinden bir fonksiyondur, etki alanı kümesi,
aralık kümesindeki değerlere Sonlu eşlemeler, iki farklı kategoriyi modellemektedir.
programlama dillerinde, işlevlerde ve dizilerde türler, ancak bazı dillerde
guages ​​fonksiyonları tip değildir. Tüm diller, tanımlanmış dizileri içerir.
dizinleri dizideki öğelere eşleyen bir eşleme işlevi açısından. İçin
geleneksel dizilerde, eşleme basittir—tamsayı değerleri
dizi elemanlarının adresleri; ilişkisel diziler için, eşleme şu şekilde tanımlanır:
bir karma işlemini açıklayan işlev. Karma işlevi,
ortak Dizilerin tuşları, genellikle karakter dizeleri, 11 adreslerine
dizi öğeleri.
Bir Kartezyen veya n kümenin çapraz çarpımı, S 1 , S 2 , c , Sn ,
S 1 * S 2 * c * S n ile gösterilen bir kümedir . Her bir elemanın
11. Ruby ve Lua'da, ilişkisel dizi anahtarlarının karakter dizileri olması gerekmez - herhangi bir türde olabilirler.

Sayfa 331
310
Bölüm 6 Veri Tipleri
Kartezyen çarpım kümesi, oluşturan kümelerin her birinden bir elemana sahiptir. Böyle,
S 1 * S 2 = {(x, y) x S 1'de ve y S 2'de }. Örneğin, S 1 = {1, 2} ise ve
S 2 = {a, b}, S 1 * S 2 = {(1, a), (1, b), (2, a), (2, b)}. Kartezyen bir ürün tanımlar
bir veri türü olarak Python, ML ve F#'ta görünen matematikteki demetler (bkz.
Bölüm 6.5). Kartezyen ürünler aynı zamanda kayıtları veya yapıları modellemektedir.
Kesinlikle. Kartezyen ürünlerin eleman adları yoktur, ancak kayıtlar şunları gerektirir:
onlara. Örneğin, aşağıdaki C yapısını göz önünde bulundurun:
struct intFloat {
int myInt;
yüzer myFloat;
};
Bu yapı, Kartezyen ürün tipini int * float tanımlar . isimleri
elemanlardır myInt ve myFloat .
İki kümenin birleşimi, S 1 ve S 2 , S 1 h S 2 = {xx, S 1 veya x'dedir olarak tanımlanır.
S 2 }'dedir. Birleşim modellerini, Bölüm 6.10'da açıklandığı gibi birleşim veri türlerini ayarlayın.
Matematiksel altkümeler, öğelerin zorunlu olması gereken bir kural sağlanarak tanımlanır.
takip et. Bu kümeler, tam olarak olmasa da, Ada'nın alt türlerini modellemektedir, çünkü
alt türler, üst kümelerinin bitişik öğelerinden oluşmalıdır. Unsurları
matematiksel kümeler sırasızdır, bu nedenle model mükemmel değildir.
C'deki * gibi tür operatörleriyle tanımlanan işaretçilerin
küme işlemi olarak tanımlanır.
Bu, veri türlerindeki formalizm tartışmamızın yanı sıra
tüm veri türleri tartışması.
ÖZET
Bir dilin veri türleri, o dilin özelliklerini belirleyen şeyin büyük bir parçasıdır.
stil ve kullanışlılık. Kontrol yapılarıyla birlikte, bir sistemin kalbini oluştururlar.
dilim.
Çoğu zorunlu dilin ilkel veri türleri arasında sayısal,
karakter ve Boole türleri. Sayısal türler genellikle doğrudan desteklenir
donanım tarafından.
Kullanıcı tanımlı numaralandırma ve alt aralık türleri uygundur ve
programların okunabilirliği ve güvenilirliği.
Diziler çoğu programlama dilinin bir parçasıdır. Aralarındaki ilişki
bir dizi öğesine bir başvuru ve bu öğenin adresi şurada verilmiştir:
eşlemenin bir uygulaması olan bir erişim işlevi. diziler olabilir
ya statik, tanımı statik belirteci içeren C++ dizilerinde olduğu gibi ;
sabit yığın dinamik, C işlevlerinde olduğu gibi ( statik belirteç olmadan ); yığın-
Ada bloklarında olduğu gibi dinamik; Java'nın nesnelerinde olduğu gibi sabit yığın dinamiği; veya yığın
Perl dizilerinde olduğu gibi dinamik. Çoğu dil üzerinde yalnızca birkaç işleme izin verir.
tam diziler.

Sayfa 332
Bibliyografik Notlar 311
Kayıtlar artık çoğu dilde bulunmaktadır. Kayıt alanları belirtilir
bir çok yoldan. COBOL söz konusu olduğunda, bunlara başvurulmadan başvurulabilir.
Uygulaması dağınık olmasına rağmen, ekteki tüm kayıtları adlandırmak ve
okunabilirliğe zararlıdır. Nesne yönelimli pro-
gramlama, kayıtlar nesnelerle desteklenir.
Tuple'lar kayıtlara benzer, ancak bileşenlerinin isimleri yoktur.
parçalar. Python, ML ve F#'ın parçasıdırlar.
Listeler, işlevsel programlama dillerinin temel öğeleridir, ancak artık aynı zamanda
Python ve C#'a dahildir.
Birlikler, farklı zamanlarda farklı tür değerleri depolayabilen konumlardır.
Ayrımcı birleşimler, geçerli tür değerini kaydetmek için bir etiket içerir. Bedava
sendika etiketi olmayan birdir. Birleşimleri olan çoğu dilde güvenli yoktur
onlar için tasarımlar, istisnalar Ada, ML ve F#'dır.
İşaretçiler, esnekliği adreslemek ve dinamik depolamayı kontrol etmek için kullanılır
yönetmek. İşaretçilerin bazı doğal tehlikeleri vardır: Sarkan işaretçiler farklıdır.
kaçınılması gerekir ve bellek sızıntısı meydana gelebilir.
Java ve C#'dakiler gibi referans türleri yığın yönetimi sağlar
işaretçilerin tehlikeleri olmadan.
Bir veri tipini uygulamadaki zorluk seviyesi, üzerinde güçlü bir etkiye sahiptir.
türün bir dile dahil edilip edilmeyeceği. Numaralandırma türleri, alt aralık
türleri ve kayıt türlerinin uygulanması nispeten kolaydır. Diziler ayrıca
basit, ancak dizi öğesi erişimi,
dizi birkaç aboneye sahiptir. Erişim işlevi, bir ekleme ve bir
her alt simge için çarpma.
Yığın yönetimi uygun değilse, işaretçilerin uygulanması nispeten kolaydır.
taraflı. Tüm hücreler aynı boyuta sahipse ancak yığın yönetimi nispeten kolaydır.
değişken boyutlu hücre tahsisi ve serbest bırakma için karmaşıktır.
Güçlü yazma, tüm tür hatalarının algılanmasını gerektiren kavramdır.
Güçlü yazmanın değeri artan güvenilirliktir.
Bir dilin tür denklik kuralları, hangi işlemlerin gerçekleştirileceğini belirler.
bir dilin yapılandırılmış türleri arasında yasal. İsim türü denkliği ve
yapı türü eşdeğerliği, türü tanımlamaya yönelik iki temel yaklaşımdır.
denklik. Tip teorileri birçok alanda geliştirilmiştir. Bilgisayarda
bilim, tip teorisinin pratik dalı, türlerini ve tip kurallarını tanımlar.
Programlama dilleri. Küme teorisi, yapının çoğunu modellemek için kullanılabilir.
programlama dillerinde türetilmiş veri türleri.
KAYNAKÇA NOTLAR
Veri tipi tasarımı, kullanımı ve kullanımı ile ilgili çok sayıda literatür mevcuttur.
uygulama. Hoare, yapının en eski sistematik tanımlarından birini verir.
Dahl ve ark. (1972). Çok çeşitli verilerin genel bir tartışması
türleri Cleaveland'de (1986) verilmiştir.

Sayfa 333
312
Bölüm 6 Veri Tipleri
Pascal'ın olası güvensizlikleri üzerinde çalışma zamanı kontrolleri uygulamak
veri türleri Fischer ve LeBlanc'ta (1980) tartışılmıştır. Çoğu derleyici
Fischer ve LeBlanc (1991) ve Aho ve diğerleri gibi tasarım kitapları. (1986),
diğer programların yaptığı gibi, veri türleri için uygulama yöntemlerini açıklayın.
Pratt ve Zelkowitz (2001) ve Scott (2000) gibi dil metinleri.
Yığın yönetimi sorunlarının ayrıntılı bir tartışması burada bulunabilir.
Tenenbaum et al. (1990). Çöp toplama yöntemleri tarafından geliştirilmiştir.
Schorr ve Waite (1967) ve Deutsch ve Bobrow (1976). Kapsamlı bir
çöp toplama algoritmaları tartışması Cohen'de (1981) bulunabilir.
ve Wilson (2005).
İNCELEME SORULARI
1. Tanımlayıcı nedir?
2. Ondalık veri türlerinin avantajları ve dezavantajları nelerdir?
3. Karakter dizisi türleri için tasarım sorunları nelerdir?
4. Üç dizi uzunluğu seçeneğini tanımlayın.
5. Sıra , numaralandırma ve alt aralık türlerini tanımlayın .
6. Kullanıcı tanımlı numaralandırma türlerinin avantajları nelerdir?
7. Kullanıcı tanımlı C# numaralandırma türleri hangi yönlerden daha güvenilirdir?
C++'dakilerden daha mı?
8. Diziler için tasarım sorunları nelerdir?
9. Statik , sabit yığın dinamik , yığın dinamik , sabit yığın dinamik ve
yığın dinamik diziler . Her birinin avantajları nelerdir?
10. Bir dizinin var olmayan bir elemanına başvurulduğunda ne olur?
Perl'de mi?
11. JavaScript seyrek dizileri nasıl destekler?
12. Negatif abonelikleri hangi diller destekler?
13. Hangi diller, adım boyutlu dizi dilimlerini destekler?
14. Ada'da mevcut olmayan hangi dizi başlatma özelliği mevcut?
diğer ortak zorunlu diller?
15. Toplam sabit nedir?
16. Tek boyutlu için özel olarak hangi dizi işlemleri sağlanır?
Ada'daki diziler?
17. Satır ana sırasını ve sütun ana sırasını tanımlayın .
18. Bir dizi için erişim işlevi nedir?
19. Bir Java dizisi tanımlayıcısında gerekli girişler nelerdir ve ne zaman yapılmalıdır?
saklanacaklar mı (derleme zamanında veya çalışma zamanında)?
20. Bir ilişkisel dizinin yapısı nedir?

Sayfa 334
Soruları gözden geçir 313
21. COBOL kayıtlarındaki seviye numaralarının amacı nedir?
22. Kayıtlardaki alanlara tam nitelikli ve eliptik referanslar tanımlayın .
23. Bir kayıt ve bir demet arasındaki temel fark nedir?
24. Python demetleri değişebilir mi?
25. Bir F# demet modelinin amacı nedir?
26. Listeler hangi öncelikli emir dilinde dizi görevi görür?
27. Şema fonksiyonunun CAR eylemi nedir ?
28. F# fonksiyonunun tl eylemi nedir ?
29. Scheme'in CDR işlevi parametresini ne şekilde değiştirir?
30. Python'un liste kavrayışları neye dayanmaktadır?
31. Sendika , serbest sendika ve ayrımcı sendikayı tanımlayın .
32. Sendikalar için tasarım konuları nelerdir?
33. Ada birleşimleri her zaman kontrol ediliyor mu?
34. F# sendikaları ayrımcılığa maruz kalıyor mu?
35. İşaretçi türleri için tasarım sorunları nelerdir?
36. İşaretçilerle ilgili yaygın iki sorun nelerdir?
37. Neden çoğu dilin işaretçileri tek bir noktayı işaret etmekle sınırlıdır?
değişken türü?
38. C++ referans türü nedir ve yaygın kullanımı nedir?
39. C++'daki referans değişkenler neden biçimsel işaretçilerden daha iyidir?
parametreler?
40. Java ve C# referans tipi değişkenlerin aşağıdakilere göre ne gibi avantajları vardır?
işaretçiler diğer dillerde?
41. Çöpleri geri kazanmaya yönelik tembel ve istekli yaklaşımları tanımlayın.
42. Java ve C# referanslarında aritmetik neden mantıklı olmasın?
43. Uyumlu tip nedir?
44. Tip hatasını tanımlayın.
45. Kesinlikle yazılanları tanımlayın.
46. ​​Java neden güçlü bir şekilde yazılmıyor?
47. Dönüştürmeyen oyuncu kadrosu nedir?
48. Hangi dillerde tür zorlaması yoktur?
49. C ve C++ neden güçlü bir şekilde yazılmıyor?
50. İsim türü denkliği nedir?
51. Yapı tipi denkliği nedir?
52. Ad türü denkliğinin birincil avantajı nedir?
53. Yapı tipi denkliğinin birincil dezavantajı nedir?
54. C hangi tipler için yapı tipi denkliğini kullanır?
55. C'nin yapı veri tipini hangi set operasyon modelleri ?

Sayfa 335
314
Bölüm 6 Veri Tipleri
PROBLEM SETİ
1. Boolean değerlerinin şu şekilde temsil edilmesinin lehine ve aleyhine olan argümanlar nelerdir?
bellekte tek bit?
2. Bir ondalık değer bellek alanını nasıl boşa harcar?
3. VAX mini bilgisayarları, kayan noktalı sayılar için bir biçim kullanır.
IEEE standardı ile aynı değildir. Bu biçim nedir ve neden
VAX bilgisayarların tasarımcıları tarafından mı seçildi? VAX için bir referans
kayan nokta gösterimleri Sebesta'dır (1991).
4. Sarkmadan kaçınmak için mezar taşı ve kilitle-anahtar yöntemlerini karşılaştırın
işaretçiler, güvenlik ve uygulama maliyeti açısından.
5. İşaretçilerin örtük olarak referanstan çıkarılmasında ne gibi dezavantajlar vardır,
ama sadece belirli bağlamlarda? Örneğin, örtük deref-
bir referansa referans vermek için kullanıldığında Ada'daki bir kayda bir işaretçinin erence
kayıt alanı.
6. Ada'nın alt türleri ile türetilmiş türleri arasındaki tüm farkları açıklayın.
7. C ve C++' da -> operatörü için hangi önemli gerekçe var ?
8. C++'ın numaralandırma türleri arasındaki tüm farklar nelerdir?
ve Java'nınkiler?
9. C ve C++'daki birleşimler, bu lan- ların kayıtlarından ayrıdır.
Ada'da olduğu gibi birleştirmek yerine ölçüler. avan-
Bu iki seçeneğin dezavantajları ve dezavantajları nelerdir?
10. Çok boyutlu diziler, C++'da olduğu gibi satır ana düzeninde saklanabilir veya
Fortran'da olduğu gibi sütun ana sırasına göre. için erişim işlevlerini geliştirin.
bu düzenlemelerin her ikisi de üç boyutlu diziler için.
11. Burroughs Extended ALGOL dilinde matrisler,
matrisin satırlarına yönelik tek boyutlu işaretçiler dizisi,
tek boyutlu değer dizileri olarak ele alınır. Avantajları nelerdir
ve böyle bir planın dezavantajları?
12. C'nin malloc ve free fonksiyonlarının bir karşılaştırmasını analiz edin ve yazın.
C++'ın yeni ve silme operatörleri. Birincil düşünce olarak güvenliği kullanın-
karşılaştırmada yer almaktadır.
13. C++ işaretçilerini ve Java referansını kullanmanın bir karşılaştırmasını analiz edin ve yazın
sabit yığın dinamik değişkenlere atıfta bulunmak için değişkenler. Güvenlik kullanın ve
Nience karşılaştırmada birincil hususlar olarak.
14. Java'da nelerin kaybedildiği ve nelerin kazanıldığı hakkında kısa bir tartışma yazın.
tasarımcıların C++ işaretçilerini dahil etmeme kararı.
15. Java'nın örtük yığın deposunun lehine ve aleyhine olan argümanlar nelerdir?
açık yığın depolama kurtarma ile karşılaştırıldığında yaş kurtarma
C++'da gerekli mi? Gerçek zamanlı sistemleri düşünün.
16. Numaralandırma türlerinin C#'a dahil edilmesi için argümanlar nelerdir,
Java'nın ilk birkaç sürümünde olmasalar da?

Sayfa 336
Programlama Alıştırmaları 315
17. C#'ta işaretçilerin kullanım düzeyinin ne olmasını beklersiniz? Nasıl
kesinlikle gerekli olmadığında sıklıkla kullanılacaklar mı?
18. Biri aşağıdakileri gerektirenler için olmak üzere iki matris uygulamaları listesi yapın.
pürüzlü matrisler ve dikdörtgen matrisler gerektirenler için bir tane.
Şimdi, sadece pürüzlü mü, sadece dikdörtgen mi, yoksa her ikisinin birden mi olması gerektiğini tartışın.
bir programlama diline dahildir.
19. Sınıf kitaplıklarının dize işleme yeteneklerini karşılaştırın.
C++, Java ve C#.
20. Gehani'de (1983) verilen güçlü tip tanımına bakın ve
bu bölümde verilen tanımla karşılaştırın. Nasıl farklılık gösterirler?
21. Statik tip kontrolü hangi yönden dinamik tip kontrolünden daha iyidir?
22. Zorlama kurallarının, güçlü kuralların faydalı etkisini nasıl zayıflatabileceğini açıklayın.
yazıyor?
PROGRAMLAMAALIŞTIRMALAR
1. Tip uyumluluğunu belirlemek için bir dizi basit test programı tasarlayın
erişiminiz olan bir C derleyicisinin kuralları. Raporunuzu yazın
bulgular.
2. Erişiminiz olan bir C derleyicisinin uygulanıp uygulanmadığını belirleyin.
meler serbest fonksiyonu.
3. Bir dilde matris çarpımı yapan bir program yazın.
alt simge aralığı denetimi yapar ve bunun için bir derleme edinebilirsiniz
derleyiciden dil veya makine dili sürümü. Belirlemek
alt simge aralığı kontrolü için gerekli talimat sayısı ve
matris çarpımı için toplam talimat sayısıyla karşılaştırın.
katyon süreci.
4. Kullanıcının belirtebileceği bir derleyiciye erişiminiz varsa,
alt simge aralığı kontrolü isteniyorsa, büyük bir işlem yapan bir program yazın
matris erişimlerinin sayısı ve yürütme zamanları. Programı çalıştır
alt simge aralığı denetimi ile ve onsuz ve süreleri karşılaştırın.
5. C++ ile basit bir program yazın ve numaralandırmanın güvenliğini araştırın.
tipler. Numaralandırma türlerine en az 10 farklı işlem ekleyin
hangi yanlış veya sadece aptalca şeylerin yasal olduğunu belirlemek için. Şimdi, bir C# yazın
kaç tane olduğunu belirlemek için aynı şeyleri yapan ve çalıştıran program
yanlış veya aptalca şeyler yasaldır. Sonuçlarınızı karşılaştırın.
6. İki farklı numaralandırma içeren C++ veya C# dilinde bir program yazın
türleri ve numaralandırmayı kullanan önemli sayıda işlemi vardır.
türleri. Ayrıca aynı programı sadece tamsayı değişkenlerini kullanarak yazın. iletişim
okunabilirliği karşılaştırın ve arasındaki güvenilirlik farklarını tahmin edin.
iki program.

Sayfa 337
316
Bölüm 6 Veri Tipleri
7. Öğelere çok sayıda başvuru yapan bir C programı yazın
yalnızca abonelik kullanarak iki boyutlu diziler. bir saniye yaz
Aynı işlemleri yapan ancak işaretçiler ve işaretçiler kullanan program
dizi başvurularını yapmak için depolama eşleme işlevi için aritmetik.
İki programın zaman verimliliğini karşılaştırın. İkisinden hangisi
programlar daha güvenilir olabilir mi? Niye ya?
8. Karma ve çok sayıda işlem kullanan bir Perl programı yazın
hash üzerinde. Örneğin, hash insanların isimlerini ve onların isimlerini saklayabilir.
yaşlar. Üç karakter oluşturmak için rastgele sayı üreteci kullanılabilir
karmaya eklenebilecek isimler ve yaşlar. Ne zaman bir kopya
ad oluşturuldu, karmaya erişime neden olur, ancak bir
yeni eleman. Aynı programı hash kullanmadan yeniden yazın. Karşılaştırmak
ikisinin yürütme verimliliği. Programlama kolaylığını karşılaştırın
ve ikisinin okunabilirliği.
9. Seçtiğiniz dilde farklı davranan bir program yazın.
enly, eğer dil yapısal kullandıysa, isim eşdeğerliğini kullanıyorsa
denklik.
10. A = B basit atama ifadesi hangi A ve B türleri için geçerlidir?
C++'da yasal ama Java değil mi?
11. Basit atama ifadesi A = B ne tür A ve B için
Java'da yasal ama Ada'da değil mi?

Sayfa 338
317
7.1 Giriş
7.2 Aritmetik İfadeler
7.3 Aşırı Yüklenmiş Operatörler
7.4 Tip Dönüşümleri
7.5 İlişkisel ve Boole İfadeleri
7.6 Kısa Devre Değerlendirmesi
7.7 Atama İfadeleri
7.8 Karma Mod Atama
7
ifadeler ve
Atama İfadeleri

Sayfa 339
318
Bölüm 7 İfadeler ve Atama İfadeleri
A s başlığı bu bölümün konusu ifadeleri ve görevi olarak, olduğunu, belirten
ifadeler. Değerlendirme sırasını belirleyen semantik kurallar
İlk önce ifadelerde operatörlerin kullanımı tartışılmıştır. Bunu takip eden bir
işlevler olduğunda işlenen değerlendirme sırası ile olası bir sorunun açıklaması
yan etkileri olabilir. Hem önceden tanımlanmış hem de kullanıcı tanımlı aşırı yüklenmiş operatörler,
daha sonra programlardaki ifadeler üzerindeki etkileri ile birlikte tartışılmıştır. Sonraki,
karma kipli ifadeler açıklanır ve değerlendirilir. Bu tanımlamaya yol açar
ve hem örtük hem de genişleyen ve daraltan tür dönüşümlerinin değerlendirilmesi
açık. İlişkisel ve Boolean ifadeler daha sonra pro-
kısa devre değerlendirmesi. Son olarak, en basitinden atama ifadesi
ifadeler olarak atamalar ve
karma mod atamaları.
Karakter dizisi desen eşleştirme ifadeleri, çalışmanın bir parçası olarak ele alındı.
Bölüm 6'daki karakter dizileriyle ilgili materyal, bu nedenle bu bölümde bahsedilmemiştir.
7.1 Giriş
İfadeler, bir programda hesaplamaları belirtmenin temel araçlarıdır.
gramer dili. Bir programcının her ikisini de anlaması çok önemlidir.
kullanılan dilin ifadelerinin sözdizimi ve semantiği. Resmi bir
ifadelerin sözdizimini açıklamak için mekanizma (BNF) tanıtıldı
Bölüm 3. Bu bölümde, ifadelerin anlambilimi tartışılmaktadır.
İfade değerlendirmesini anlamak için,
operatör emirleri ve işlenen değerlendirme. Operatör değerlendirme sırası
ifadeler, dilin çağrışım ve öncelik kuralları tarafından belirlenir.
Bir ifadenin değeri bazen ona bağlı olsa da, işlem sırası
ve ifadelerdeki değerlendirme genellikle dil tasarımcıları tarafından belirtilmez. Bu izin verir
uygulayıcıların, programların olasılığına yol açan sırayı seçmeleri
farklı uygulamalarda farklı sonuçlar üretmektedir. Diğer konular ifade-
semantics tür uyumsuzlukları, zorlamalar ve kısa devre değerlendirmesidir.
Zorunlu programlama dillerinin özü baskındır.
atama ifadelerinin rolü. Bu açıklamaların amacı,
programın değişken değerlerini veya durumunu değiştirmenin yan etkisi. Böyle
tüm zorunlu dillerin ayrılmaz bir parçası, değişkenler kavramıdır.
değerler program yürütme sırasında değişir.
İşlevsel diller, parametre gibi farklı türden değişkenler kullanır.
fonksiyonların eterleri. Bu dillerde ayrıca bağlayıcı bildirim ifadeleri vardır.
isimlere değer verir. Bu bildirimler atama ifadelerine benzer, ancak
yan etkileri yoktur.
7.2 Aritmetik İfadeler
Matematikte bulunanlara benzer aritmetik ifadelerin otomatik olarak değerlendirilmesi.
matematik, bilim ve mühendislik, ilk dönemin başlıca hedeflerinden biriydi.

Sayfa 340
7.2 Aritmetik İfadeler 319
üst düzey programlama dilleri. Aritmetiğin özelliklerinin çoğu
programlama dillerindeki ifadeler,
matematikte gelişmiştir. Programlama dillerinde, aritmetik ifadeler
operatörler, işlenenler, parantezler ve işlev çağrılarından oluşur. Operatör
tekli olabilir , yani tek bir işlenene sahiptir, ikili , yani iki işlenene sahiptir
işlenenler veya üçlü , yani üç işleneni vardır.
Çoğu programlama dilinde, ikili operatörler infix'dir , yani
işlenenleri arasında görünürler. Bir istisna, bazı özelliklere sahip olan Perl'dir.
önek olan operatörler , yani işlenenlerinden önce gelirler.
Bir aritmetik ifadenin amacı, bir aritmetik işlem belirtmektir.
varsayım. Böyle bir hesaplamanın uygulanması iki eyleme neden olmalıdır:
genellikle bellekten işlenenleri getirmek ve aritmetik işlemleri yürütmek
bu işlenenler üzerinde Aşağıdaki bölümlerde, ortak
aritmetik ifadelerin tasarım detayları.
Aritmetik ifadeler için birincil tasarım konuları aşağıdadır;
Bu bölümde tartışılanlar:
• Operatör öncelik kuralları nelerdir?
• Operatör ilişkilendirme kuralları nelerdir?
• İşlenen değerlendirmenin sırası nedir?
• İşlenen değerlendirme yan etkileri konusunda kısıtlamalar var mı?
• Dil, kullanıcı tanımlı operatör aşırı yüklemesine izin veriyor mu?
• İfadelerde hangi tür karıştırmaya izin verilir?
7.2.1 Operatör Değerlendirme Sırası
Bir dilin operatör önceliği ve ilişkilendirme kuralları, sırayı belirler.
operatörlerinin değerlendirilmesi.
7.2.1.1 Öncelik
Bir ifadenin değeri, en azından kısmen değerlendirme sırasına bağlıdır.
ifadedeki operatörlerin sayısı. Aşağıdaki ifadeyi göz önünde bulundurun:
a + b * c
a , b ve c değişkenlerinin sırasıyla 3 , 4 ve 5 değerlerine sahip olduğunu varsayalım . Eğer
soldan sağa değerlendirilir (önce toplama ve sonra çarpma), sonuç
bir 35 . Sağdan sola değerlendirilirse sonuç 23 olur .
Soldan sağa bir ifadedeki operatörleri basitçe değerlendirmek yerine
sağdan veya sağdan sola, matematikçiler uzun zaman önce yerleştirme kavramını geliştirdiler
değerlendirme öncelikleri hiyerarşisinde ve değerlendirme sırasını temel alarak operatörler
kısmen bu hiyerarşide ifadeler. Örneğin, matematikte çoklu
plikasyon eklemeden daha yüksek önceliğe sahip olarak kabul edilir, belki de
daha yüksek karmaşıklık seviyesi. Bu konvansiyon daha önce uygulanmış olsaydı

Sayfa 341
320
Bölüm 7 İfadeler ve Atama İfadeleri
Örnek ifade, çoğu programlama dilinde olduğu gibi,
önce çarpma işlemi yapılacaktı.
Operatör öncelik kuralları ekspresyonunun değerlendirilmesi için kısmen tanımlamak
farklı öncelik seviyelerindeki operatörlerin değerlendirildiği sıra.
İfadeler için operatör öncelik kuralları, aşağıdaki hiyerarşiye dayanmaktadır:
dil tasarımcısı tarafından görüldüğü gibi operatör öncelikleri. operatör önceliği
ortak zorunlu dillerin kuralları hemen hemen aynıdır, çünkü
matematiğinkilere dayanırlar. Bu dillerde üstelleştirme
en yüksek önceliğe sahiptir (dil tarafından sağlandığında), ardından
aynı seviyede çarpma ve bölme, ardından ikili toplama ve
aynı seviyede çıkarma.
Birçok dil, toplama ve çıkarma işlemlerinin tekli versiyonlarını da içerir.
Tekli toplama, genellikle ilişkili bir işlem içermediğinden kimlik operatörü olarak adlandırılır.
işlemdir ve bu nedenle işleneni üzerinde hiçbir etkisi yoktur. Ellis ve Stroustrup (1990, s. 56),
C++ hakkında konuşmak, tarihsel bir kaza olarak adlandırın ve doğru bir şekilde işe yaramaz olarak etiketleyin. tekli
eksi, elbette, işlenenin işaretini değiştirir. Java ve C#'da tekli eksi ayrıca
kısa ve bayt işlenenlerin örtük olarak int türüne dönüştürülmesine neden olur .
Tüm ortak zorunlu dillerde, birli eksi operatörü
bir ifadede ya başında ya da ifadenin içinde herhangi bir yerde görünür.
başkasının yanında olmasını önlemek için parantez içine alındığı sürece
Şebeke. Örneğin,
a + (- b) * c
yasal ama
a + - b * c
genellikle değildir.
Ardından, aşağıdaki ifadeleri göz önünde bulundurun:
- a / b
- bir * b
- bir ** b
İlk iki durumda, birli eksi operatörünün göreli önceliği ve
ikili operatör önemsizdir—iki operatörün değerlendirme sırası
ifadesinin değeri üzerinde hiçbir etkisi yoktur. Ancak son durumda, önemli.
Yaygın programlama dillerinden yalnızca Fortran, Ruby, Visual
Basic ve Ada, üs alma operatörüne sahiptir. Dördünde de üstelleştirme
tekli eksiden daha yüksek önceliğe sahiptir, bu nedenle
- Bir ** B
eşdeğerdir
-(A ** B)

Sayfa 342
7.2 Aritmetik İfadeler 321
Ruby ve C tabanlı aritmetik operatörlerin öncelikleri
diller aşağıdaki gibidir:
** operatör üs alma olduğunu. % Operatör iki int'i
işlenen ve ikinciye bölündükten sonra ilkin kalanını verir. 1
C-tabanlı dillerin ++ ve -- operatörleri Bölüm 7.7.4'te açıklanmıştır.
APL, diller arasında tektir, çünkü tek bir öncelik düzeyine sahiptir.
sonraki bölümde gösterilmiştir.
Öncelik, operatörün sırasına ilişkin kuralların yalnızca bazılarını açıklar
değerlendirme; çağrışım kuralları da onu etkiler.
7.2.1.2 İlişkilendirme
Aşağıdaki ifadeyi göz önünde bulundurun:
a - b + c - d
Toplama ve çıkarma operatörleri aynı öncelik düzeyine sahipse,
programlama dillerinde yaparlar, öncelik kuralları hakkında hiçbir şey söylemez
Bu ifadedeki operatörlerin değerlendirme sırası.
Bir ifade, iki bitişik 2 işleç örneği içerdiğinde:
aynı öncelik seviyesi, önce hangi operatörün değerlendirildiği sorusu
dilin çağrışım kuralları tarafından cevaplanır . Bir operatör sahip olabilir
ya sol ya da sağ ilişkilendirme, yani iki bitişik olduğunda
operatörler aynı önceliğe sahipse, önce sol operatör değerlendirilir veya
önce sağ operatör sırasıyla değerlendirilir.
Ortak dillerde çağrışımsallık soldan sağadır, ancak açık-
nentiation operatörü (sağlandığında) bazen sağdan sola ilişkilendirir. İçinde
Java ifadesi
a - b + c
önce sol operatör değerlendirilir.
1. C99'dan önceki C sürümlerinde, % operatörü bazı durumlarda uygulamaya bağımlıydı.
çünkü bölünme de uygulamaya bağlıydı.
2. Operatörler tek bir işlenenle ayrılmışlarsa "bitişik" olarak adlandırılırlar.
yakut
C Tabanlı Diller
En yüksek
**
postfix ++ , --
tekli + , -
önek ++ , -- , tekli + , -
* , / , %
* , / , %
En düşük
ikili + , -
ikili + , -

Sayfa 343
322
Bölüm 7 İfadeler ve Atama İfadeleri
Fortran ve Ruby'deki üs alma doğru çağrışımlıdır, bu nedenle ifadede
A ** B ** C
önce doğru operatör değerlendirilir.
Ada'da üs alma ilişkisel değildir, yani ifade
A ** B ** C
yasa dışıdır. Böyle bir ifade, istenen sırayı göstermek için parantez içine alınmalıdır,
ikisinde de olduğu gibi
(A ** B) ** C
veya
Bir ** (B ** C)
Visual Basic'te, üs alma operatörü ^ , ilişkisel bırakılır.
Birkaç ortak dil için ilişkilendirme kuralları burada verilmiştir:
APL'de Bölüm 7.2.1.1'de belirtildiği gibi, tüm operatörler aynı
öncelik. Böylece, APL ifadelerinde operatörlerin değerlendirme sırası şu şekildedir:
tamamen tüm işlemler için sağdan sola doğru olan ilişkilendirme kuralı tarafından belirlenir.
tor. Örneğin, ifadede
A × B + C
önce toplama operatörü, ardından çarpma operatörü değerlendirilir.
(* APL çarpma operatörüdür). Eğer bir edildi 3 , B idi 4 ve C idi 5 ,
o zaman bu APL ifadesinin değeri 27 olur .
Ortak diller için birçok derleyici, bazılarının
aritmetik operatörler matematiksel olarak ilişkiseldir, yani
hareketlilik kurallarının, yalnızca bunları içeren bir ifadenin değeri üzerinde hiçbir etkisi yoktur.
operatörler. Örneğin, toplama matematiksel olarak ilişkiseldir, yani matematikte
ics ifadenin değeri
Dilim
ilişkilendirme Kuralı
yakut
Sol: * , / , + , -
Sağ: **
C tabanlı diller
Sol: * , / , % , ikili + , ikili -
Sağ: ++ , -- , tekli - , tekli +
Ada
Sol: ** hariç tümü
İlişkisel olmayan: **

Sayfa 344
7.2 Aritmetik İfadeler 323
A + B + C
operatör değerlendirme sırasına bağlı değildir. kayan nokta işlemi ise
matematiksel olarak çağrışımsal işlemler için de çağrışımsaldı,
piler, bazı basit optimizasyonları gerçekleştirmek için bu gerçeği kullanabilir. özellikle, eğer
derleyicinin operatörlerin değerlendirmesini yeniden düzenlemesine izin verilir, mümkün olabilir
ifade değerlendirmesi için biraz daha hızlı kod üretmek. Derleyiciler genellikle
Bu tür optimizasyonları yapın.
Ne yazık ki, bir bilgisayarda hem kayan nokta gösterimleri hem de
kayan noktalı aritmetik işlemler, yalnızca matematiklerinin yaklaşık değerleridir.
matematiksel muadilleri (boyut sınırlamaları nedeniyle). bir matematik olduğu gerçeği
cal operatörü birleştiricidir, mutlaka karşılık gelen
kayan nokta işlemi ilişkiseldir. Aslında, yalnızca tüm işlenenler ve
ara sonuçlar tam olarak kayan nokta gösteriminde temsil edilebilir
süreç tam olarak ilişkisel olabilir. Örneğin, patolojik durum-
bir bilgisayarda tamsayı toplamanın ilişkisel olmadığı durumlar . Örneğin,
bir programın ifadeyi değerlendirmesi gerektiğini varsayalım
A + B + C + D
ve A ve C çok büyük pozitif sayılardır ve B ve D negatif sayılardır.
çok büyük mutlak değerlere sahip bers. Bu durumda, ekleme B için A yapmaz
bir taşma özel durumuna neden, ama eklemeden C için A yapar. Benzer şekilde, ilave C için B
taşma nedeni değil, ama eklemeden D için B yapar. Sınırlamaları nedeniyle
bilgisayar aritmetiği, toplama bu durumda feci şekilde ilişkisel değildir.
Bu nedenle, derleyici bu toplama işlemlerini yeniden sıralarsa,
ifadenin değeri. Bu sorun, elbette, profesyoneller tarafından önlenebilir.
dilbilgisi, değişkenlerin yaklaşık değerlerinin bilindiği varsayılarak. bu
programcı ifadeyi iki kısımda belirtebilir (iki atama durumunda-
mentler), taşmanın önlenmesini sağlamak. Ancak bu durum aşağıdaki durumlarda ortaya çıkabilir.
programcının sırayı fark etme olasılığının düşük olduğu çok daha incelikli yollar
bağımlılık.
7.2.1.3 Parantezler
Programcılar, parantez yerleştirerek öncelik ve ilişkilendirme kurallarını değiştirebilirler.
ifadelerde tezler. Bir ifadenin parantez içine alınmış bir parçasının önceliği vardır
bitişik parantezsiz parçaları. Örneğin, çarpma işlemi olmasına rağmen
ifadede toplamaya göre öncelik
(A + B) * C
ekleme ilk olarak değerlendirilecektir. Matematiksel olarak, bu tamamen doğaldır. İçinde
bu ifade, çarpma operatörünün ilk işleneni mevcut değil
parantez içindeki alt ifadedeki ekleme değerlendirilene kadar. Ayrıca
Bölüm 7.2.1.2'deki ifade şu şekilde belirtilebilir:

Sayfa 345
324
Bölüm 7 İfadeler ve Atama İfadeleri
(A + B) + (C + D)
taşmayı önlemek için.
Aritmetik ifadelerde parantez kullanımına izin veren diller,
tüm öncelik kurallarına uyun ve kalan tüm operatörleri ilişkilendirin
sağdan veya sağdan sola. Programcı istenen sırayı belirleyecektir.
parantez içinde değerlendirme. Bu yaklaşım basit olurdu çünkü hiçbir
o zaman ne yazarın ne de programların okuyucularının herhangi bir şeyi hatırlaması gerekmeyecektir.
öncelik veya ilişkilendirme kuralları. Bu planın dezavantajı,
ifadeleri yazmayı daha sıkıcı hale getirir ve aynı zamanda ciddi şekilde taviz verir.
kodun okunabilirliği. Yine de bu, Ken Iverson tarafından yapılan seçimdi.
APL'nin tasarımcısı.
7.2.1.4 Yakut İfadeleri
Ruby'nin saf nesne yönelimli bir dil olduğunu hatırlayın, bu şu anlama gelir:
diğer şeyler, değişmezler de dahil olmak üzere her veri değerinin bir nesne olduğu. Ruby desteği
içerdiği aritmetik ve mantık işlemlerinin koleksiyonunu taşır.
C tabanlı diller. Ruby'yi C tabanlı dillerden ayıran nedir?
ifadelerin alanı, tüm aritmetik, ilişkisel ve atama
operatörlerin yanı sıra dizi indeksleme, kaydırmalar ve bitsel mantık operatörleri
yöntemler olarak uygulanmaktadır. Örneğin, a + b ifadesi ,
+ Tarafından başvurulan bir nesne gibi bir yöntem , bir nesne geçen başvurulan b olarak
bir parametre.
Operatörlerin yöntem olarak uygulanmasının ilginç bir sonucu şudur:
uygulama programları tarafından geçersiz kılınabilir. Bu nedenle, bu opera-
tor'lar yeniden tanımlanabilir. için operatörleri yeniden tanımlamak çoğu zaman yararlı olmasa da
Önceden tanımlanmış türleri tanımlamak için, Bölüm 7.3'te göreceğimiz gibi, önceden tanımlanmış türleri tanımlamak yararlıdır.
operatör aşırı yüklemesi ile yapılabilecek kullanıcı tanımlı türler için operatörler
bazı dillerde.
7.2.1.5 LISP'deki İfadeler
Ruby'de olduğu gibi, LISP'deki tüm aritmetik ve mantık işlemleri
alt programlardan oluşur. Ancak LISP'de alt programlar açıkça
aranan. Örneğin, LISP'de a + b * c C ifadesini belirtmek için ,
aşağıdaki ifadeyi yazın: 3
(+ bir (* bc))
Bu ifadede + ve * fonksiyonların isimleridir.
3. LISP'de bir liste kod olarak yorumlandığında, ilk öğe fonksiyon adıdır ve diğerleri
fonksiyonun parametreleridir.

Sayfa 346
7.2 Aritmetik İfadeler 325
7.2.1.6 Koşullu İfadeler
if-then-else ifadeleri koşullu bir ifade gerçekleştirmek için kullanılabilir
atama. Örneğin, düşünün
eğer (sayım == 0)
ortalama = 0;
Başka
ortalama = toplam / sayı;
C-tabanlı dillerde, bu kod daha rahat bir şekilde belirtilebilir.
forma sahip bir koşullu ifade kullanan atama ifadesi
ifade_1 ? ifade_2 : ifade_3
burada ifade_1, Boole ifadesi olarak yorumlanır. ifade_1 ise
doğru olarak değerlendirilir, tüm ifadenin değeri ifade_2'nin değeridir;
aksi takdirde, ifade_3'ün değeridir. Örneğin, örneğin etkisi
if-then-else , aşağıdaki atama ifadesi kullanılarak elde edilebilir:
koşullu ifade:
ortalama = (sayı == 0) ? 0 : toplam / sayma;
Aslında soru işareti, then cümlesinin başlangıcını gösterir ve
kolon, else yan tümcesinin başlangıcını işaretler . Her iki madde de zorunludur.
Bunu not et ? koşullu ifadelerde üçlü operatör olarak kullanılır.
Koşullu ifadeler bir programın herhangi bir yerinde kullanılabilir (C tabanlı bir
dil) başka herhangi bir ifadenin kullanılabileceği yer. C tabanlı ek olarak
diller, koşullu ifadeler Perl, JavaScript ve Ruby'de sağlanır.
7.2.2 İşlenen Değerlendirme Sırası
İfadelerin daha az tartışılan bir tasarım özelliği,
işlenenlerin değerlendirilmesi. İfadelerdeki değişkenler, değerleri getirilerek değerlendirilir.
bellekten değerler. Sabitler bazen aynı şekilde değerlendirilir. Diğer
durumlarda, bir sabit makine dili talimatının bir parçası olabilir ve
bir bellek getirme. Bir işlenen parantez içine alınmış bir ifadeyse, tüm operatörler
değeri bir işlenen olarak kullanılmadan önce içerdiği değer değerlendirilmelidir.
Bir operatörün işlenenlerinden hiçbirinin yan etkisi yoksa, işlenen
değerlendirme sırası önemsizdir. Bu nedenle, tek ilginç durum ne zaman ortaya çıkar?
bir işlenenin değerlendirilmesinin yan etkileri vardır.
7.2.2.1 Yan Etkiler
Bir yan etki , bir fonksiyon, doğal olarak fonksiyonel bir yan etkisi olarak adlandırılan, ortaya çıkar
işlev, parametrelerinden birini veya global bir değişkeni değiştirir. (Küresel
değişken, işlevin dışında bildirilir ancak işlevden erişilebilir.)

Sayfa 347
326
Bölüm 7 İfadeler ve Atama İfadeleri
ifadeyi düşünün
bir + eğlence(a)
Eğlenceli değişen yan etkisi yoksa bir değerlendirmenin ardından sırasını
iki işlenenden a ve fun(a) ifadesinin değeri üzerinde hiçbir etkisi yoktur.
Ancak, eğlenceli değiştiren bir , bir efekt vardır. Aşağıdaki durumu göz önünde bulundurun:
fun 10 değerini döndürür ve parametresinin değerini 20 olarak değiştirir . Diyelim ki
devamındaki:
a = 10;
b = a + eğlence(a);
Daha sonra ilk olarak a değeri getirilirse (ifade değerlendirme sürecinde),
değeri 10 ve ifadenin değeri 20'dir . Ama eğer ikinci işlenen
önce değerlendirilir, ardından ilk işlenenin değeri 20'dir ve
ifadesi 30'dur .
Aşağıdaki C programı aynı sorunu bir fonksiyon
bir ifadede görünen global bir değişkeni değiştirir:
int a = 5;
int eğlence1() {
a = 17;
dönüş 3;
} /* fun1'in sonu */
geçersiz ana() {
a = bir + eğlence1();
} /* ana bölümün sonu */
a in main için hesaplanan değer , değerlendirme sırasına bağlıdır.
a + fun1() ifadesinde işlenenler . Değeri bir ya olacak 8 (eğer bir
önce değerlendirilir) veya 20 (önce işlev çağrısı değerlendirilirse).
Matematikteki fonksiyonların yan etkileri olmadığına dikkat edin, çünkü
matematikte değişken kavramı yoktur. Aynısı işlevsellik için de geçerlidir
Programlama dilleri. Hem matematikte hem de fonksiyonel programlamada
diller, işlevler hakkında akıl yürütmek ve anlamak çok daha kolaydır.
zorunlu dillerde olanlar, çünkü bağlamları kendileriyle ilgisizdir.
anlam.
İşlenen değerlendirme sorununa iki olası çözüm vardır.
sipariş ve yan etkiler. İlk olarak, dil tasarımcısı işleve izin vermeyebilir
sadece işleve izin vermeyerek ifadelerin değerini etkilemekten değerlendirme
yan etkiler. İkincisi, dil tanımı, işlenenleri şu şekilde ifade edebilir:
ifadeler belirli bir sıra ve talepte değerlendirilmeli-
akıl hocaları bu düzeni garanti eder.
Zorunlu dillerde işlevsel yan etkilere izin vermemek zordur,
ve programcı için bazı esnekliği ortadan kaldırır. C durumunu düşünün
ve yalnızca işlevleri olan C++, yani tüm alt programların bir tane döndürdüğü anlamına gelir

Sayfa 348
7.2 Aritmetik İfadeler 327
değer. Çift yönlü parametrelerin yan etkilerini ortadan kaldırmak ve yine de alt-
Birden fazla değer döndüren programlarda, değerlerin yerleştirilmesi gerekir.
bir yapı içinde ve yapı döndürüldü. Fonksiyonlardaki globallere erişim de
izin verilmemesi gerekir. Bununla birlikte, verimlilik önemli olduğunda, erişimi kullanmak
parametre geçişini önlemek için global değişkenler önemli bir artış yöntemidir.
yürütme hızı. Derleyicilerde, örneğin, aşağıdakiler gibi verilere küresel erişim
sembol tablosu olağandır.
Sıkı bir değerlendirme sırasına sahip olmanın sorunu, bazı kod seçeneklerinin
Derleyiciler tarafından kullanılan mization teknikleri, işlenen değerlendirmelerinin yeniden sıralanmasını içerir.
Garantili bir sıra, işlev çağrıldığında bu optimizasyon yöntemlerine izin vermez
alakalıdır. Bu nedenle, fiili olarak doğrulandığı gibi mükemmel bir çözüm yoktur.
dil tasarımları.
Java dili tanımı, işlenenlerin değerlendiriliyormuş gibi görünmesini garanti eder.
Bu bölümde tartışılan sorunu ortadan kaldırarak soldan sağa sırayla.
7.2.2.2 Bilgi Şeffaflığı ve Yan Etkiler
Referans şeffaflığı kavramı, işlevsellikten etkilenir ve bunlardan etkilenir.
yan etkiler. Bir program, eğer herhangi ikisi varsa , referans şeffaflığı özelliğine sahiptir.
Programdaki aynı değere sahip ifadeler bir tanesinin yerine kullanılabilir.
programın eylemini etkilemeden programın herhangi bir yerinde başka bir
Referans olarak şeffaf bir fonksiyonun değeri tamamen onun parametrelerine bağlıdır.
eter. 4 Referans şeffaflığı ve fonksiyonel yan etkilerin bağlantısı
aşağıdaki örnekle gösterilmiştir:
sonuç1 = (eğlence(a) + b) / (eğlence(a) - c);
sıcaklık = eğlence(a);
sonuç2 = (temp + b) / (temp - c);
fun fonksiyonunun yan etkisi yoksa sonuç1 ve sonuç2 eşit olacaktır,
çünkü onlara atanan ifadeler eşdeğerdir. Ancak, varsayalım
fun , b veya c'ye 1 eklemenin yan etkisine sahiptir . O zaman sonuç1 olmaz
sonuç2'ye eşit olsun . Yani, bu yan etki referans şeffaflığını ihlal ediyor
kodun göründüğü programın.
Referans olarak şeffaf programların çeşitli avantajları vardır. bu
Bunlardan en önemlisi, bu tür programların anlambiliminin çok daha kolay olmasıdır.
göndergesel olarak çapraz olmayan programların semantiğinden daha iyi anlamak
ebeveyn. Referans olarak şeffaf olmak, bir fonksiyonu matematiğe eşdeğer kılar.
ematical işlevi, anlama kolaylığı açısından.
Değişkenleri olmadığı için, saf fonksiyonel olarak yazılmış programlar
diller referans olarak şeffaftır. Saf bir işlevsel dilde işlevler
yerel değişkenlerde saklanacak bir duruma sahip olamaz. eğer böyle bir fonksiyon
fonksiyonun dışından bir değer kullanır, bu değer bir sabit olmalıdır, çünkü
4. Ayrıca, fonksiyonun değeri, parametrelerinin sıralandığı sıraya bağlı olamaz.
değerlendirilir.

Sayfa 349
328
Bölüm 7 İfadeler ve Atama İfadeleri
değişkenler yoktur. Bu nedenle, fonksiyonun değeri, değerlerine bağlıdır.
onun parametreleri.
Referans şeffaflığı Bölüm 15'te daha ayrıntılı olarak tartışılacaktır.
7.3 Aşırı Yüklenmiş Operatörler
Aritmetik operatörler genellikle birden fazla amaç için kullanılır. Örneğin,
+ genellikle tamsayı eklemeyi ve kayan nokta eklemeyi belirtmek için kullanılır. Bazı
diller - örneğin Java - aynı zamanda dize dizileme için de kullanır. Bu çoklu
bir operatörün kullanımına, operatörün aşırı yüklenmesi denir ve genellikle
ne okunabilirlik ne de güvenilirlik zarar görmediği sürece kabul edilebilir.
Aşırı yüklemenin olası tehlikelerine bir örnek olarak,
C++'da ve işareti ( & ). İkili bir operatör olarak, bitsel mantıksal bir
VE operasyon. Ancak tekli bir operatör olarak anlamı tamamen farklıdır.
İşleneni bir değişken olan tekli bir operatör olarak, ifade değeri şudur:
bu değişkenin adresi. Bu durumda, ve işareti, adresin adresi olarak adlandırılır.
Şebeke. Örneğin, yürütme
x = &y;
y adresinin x içine yerleştirilmesine neden olur . Bununla birlikte iki tane sorun var
ve işaretinin çoklu kullanımı. İlk olarak, aynı sembolü tamamen iki kişi için kullanmak
ilgisiz işlemler okunabilirliğe zarar verir. İkincisi, basit anahtarlama
bit düzeyinde AND işlemi için ilk işleneni dışarıda bırakma hatası gidebilir
operatörün adresi olarak yorumlandığından derleyici tarafından algılanmaz.
Böyle bir hatayı teşhis etmek zor olabilir.
Hemen hemen tüm programlama dillerinin daha az ciddi ancak benzer bir sorunu vardır.
lem, genellikle eksi operatörünün aşırı yüklenmesinden kaynaklanır. Sorun
yalnızca derleyici, operatörün ikili mi yoksa ikili mi olduğunu söyleyemez.
tekli. 5 Bu nedenle, bir kez daha, operatör çalışırken ilk işleneni dahil etmedeki başarısızlık
ikili olması amaçlanan, derleyici tarafından bir hata olarak algılanamaz. Ancak,
İki işlemin anlamları, tekli ve ikili, en azından yakından
ilişkilidir, bu nedenle okunabilirlik olumsuz etkilenmez.
Soyut veri türlerini destekleyen bazı diller (bkz. Bölüm 11),
örneğin, C++, C# ve F#, programcının operatörü daha fazla aşırı yüklemesine izin verir
semboller. Örneğin, bir kullanıcının * operatörünü aşağıdakiler arasında tanımlamak istediğini varsayalım:
bir skaler tamsayı ve bir tamsayı dizisi, dizinin her bir öğesinin
skaler ile çarpılır. Böyle bir operatör bir yazılarak tanımlanabilir.
Bu yeni işlemi gerçekleştiren * adlı işlev alt programı . derleyici
aşırı yüklenmiş bir operatör belirtildiğinde doğru anlamı seçecektir,
dil tanımlı aşırı yüklenmiş operandlarda olduğu gibi işlenenlerin türlerine göre
tor. Örneğin, * için bu yeni tanım bir C# programında tanımlanmışsa, bir C#
5. ML, tekli ve ikili eksi operatörleri için farklı semboller kullanarak bu sorunu hafifletir,
birli için tilde (~) ve ikili için tire (–).

Sayfa 350
7.4 Tip Dönüşümleri 329
derleyici için yeni bir tanım kullanır * zaman * ile operatör görünür
sol işlenen olarak basit bir tamsayı ve sağ işlenen olarak bir tamsayı dizisi.
Makul bir şekilde kullanıldığında, kullanıcı tanımlı operatör aşırı yüklemesi okunabilirliğe yardımcı olabilir.
Örneğin, bir matris soyut veri türü için + ve * aşırı yüklenirse ve A , B ,
C ve D bu türden değişkenlerdir, o zaman
A * B + C * D
yerine kullanılabilir
MatrixAdd(MatrixMult(A, B), MatrixMult(C, D))
Öte yandan, kullanıcı tanımlı aşırı yükleme, okunabilirliğe zarar verebilir.
Bir kere, hiçbir şey bir kullanıcının çarpma anlamına gelen + tanımlamasını engellemez .
Ayrıca, bir programda * operatörünü gören okuyucu, hem
işlenenlerin türleri ve ortalamasını belirlemek için operatörün tanımı
ing. Bu tanımların herhangi biri veya tümü başka dosyalarda olabilir.
Diğer bir husus, bir yazılım sistemi oluşturma sürecidir.
farklı gruplar tarafından oluşturulan modüller. Farklı gruplar aşırı yüklenirse
aynı operatörler farklı şekillerde, bu farklılıkların açıkça olması gerekir
sistemi bir araya getirmeden önce ortadan kaldırılır.
C++, aşırı yüklenemeyen birkaç operatöre sahiptir. Bunlar arasında
sınıf veya yapı üye operatörü (.) ve kapsam çözümleme operatörü (::).
İlginç bir şekilde, operatörün aşırı yüklenmesi, C++'da olmayan özelliklerden biriydi.
Java'ya kopyalandı. Ancak, C#'da yeniden göründü.
Kullanıcı tanımlı operatör aşırı yüklemesinin uygulanması şurada tartışılmaktadır:
9. Bölüm
7.4 Tip Dönüşümleri
Tür dönüştürmeleri ya daralmakta ya da genişlemektedir. Bir daraltma Dönüşüm
bir değeri, tüm değerlerin yaklaşıklıklarını bile depolayamayan bir türe dönüştürür.
orijinal türün değerleri. Örneğin, bir dönüştürme çift a şamandıra içinde
Java daraltıcı bir dönüşümdür, çünkü double aralığı çok daha büyüktür
daha şamandıra . Bir genişletme dönüştürme türü edilene değerine dönüştürür
orijinal türün tüm değerlerinin en azından yaklaşıklıklarını içerebilir.
Örneğin, bir dönüştürme int a yüzen Java genişleyen bir dönüşümdür.
Genişletme dönüşümleri neredeyse her zaman güvenlidir, yani
dönüştürülen değer korunur. Dönüşümleri daraltmak her zaman güvenli değildir—
bazen dönüştürülen değerin büyüklüğü süreçte değiştirilir. İçin
örneğin, kayan nokta değeri 1.3E25 Java'da bir tam sayıya dönüştürülürse
program, sonuç yalnızca orijinal değerle uzaktan ilişkili olacaktır.
Genişletme dönüşümleri genellikle güvenli olsa da, dönüşümlerin azalmasıyla sonuçlanabilir.
kesinlik. Pek çok dil uygulamasında, tamsayıdan kayan noktaya
dönüşümler dönüşümleri genişletiyor, bazı hassasiyetler kaybolabilir. Örneğin,

Sayfa 351
330
Bölüm 7 İfadeler ve Atama İfadeleri
çoğu durumda, tamsayılar en az dokuz ondalık basamağa izin veren 32 bitte saklanır.
onun kesinliği. Ancak kayan nokta değerleri de 32 bit olarak depolanır.
yedi ondalık kesinlik basamağı (üs için kullanılan boşluk nedeniyle). Böyle,
tamsayıdan kayan noktaya genişletme, iki basamaklı kesinlik kaybına neden olabilir.
İlkel olmayan türlerin zorlamaları elbette daha karmaşıktır. 5. Bölümde,
dizi ve kayıt türlerinin atama uyumluluğunun komplikasyonları
tartışıldı. Bir de hangi parametre türleri ve dönüş türleri sorusu var.
bir yöntemin bir üst sınıftaki bir yöntemi geçersiz kılmasına izin verir - yalnızca türler
aynıdır, ya da başka durumlar da vardır. Bu konu ve kavram
alt sınıfların alt tipler olarak sınıflandırılması, Bölüm 12'de tartışılmaktadır.
Tür dönüşümleri açık veya örtük olabilir. Aşağıdaki iki
alt bölümlerde bu tür dönüşümler tartışılmaktadır.
7.4.1 İfadelerde Zorlama
Aritmetik ifadelerle ilgili tasarım kararlarından biri,
bir operatör farklı türlerde işlenenlere sahip olabilir. Buna izin veren diller
karma modlu ifadeler olarak adlandırılan ifadeler , konven-
bilgisayarlarda olmadığı için örtük işlenen türü dönüşümleri için
farklı türlerde işlenenler alan ikili işlemler. Hatırlayın, Bölüm-
Ter 5, zorlama, tarafından başlatılan örtük bir tür dönüştürme olarak tanımlandı.
derleyici. Programcı tarafından açıkça istenen tür dönüşümleri
zorlamalar değil, açık dönüştürmeler veya atmalar olarak adlandırılır.
Bazı operatör sembolleri aşırı yüklenmiş olsa da, bir
bilgisayar sistemi, ya donanımda ya da yazılım simülasyonunun bir seviyesinde,
dilde tanımlanan her işlenen türü ve işleç için bir işlemi vardır. 6
Statik tip bağlama kullanan bir dilde aşırı yüklenmiş operatörler için, com-
piller, operasyon türlerine göre doğru operasyon türünü seçer.
işlenenler. Bir operatörün iki işleneni aynı tipte olmadığında ve
bu dilde yasaldır, derleyici bunlardan birini seçmelidir.
zorladı ve bu zorlamanın kodunu sağlayın. Aşağıdaki tartışmada,
birkaç ortak dilin zorlama tasarım seçenekleri incelenir.
Dil tasarımcıları, aritmetikte zorlamalar konusunda hemfikir değiller.
metik ifadeler. Çok çeşitli zorlamalara karşı olanlar endişeli
bu tür zorlamalardan kaynaklanabilecek güvenilirlik sorunları ile
tip kontrolünün faydalarını azaltır. Geniş bir alanı tercih edenler
çeşitli zorlamalar daha çok esneklikteki kayıpla ilgilidir.
kısıtlamalardan. Sorun, programcıların bununla ilgilenmesi gerekip gerekmediğidir.
bu hata kategorisi veya derleyicinin bunları algılaması gerekip gerekmediği.
Sorunun basit bir örneği olarak aşağıdaki Java kodunu göz önünde bulundurun:
int a;
yüzer b, c, d;
. . .
d = b * bir;
6. Bu varsayım birçok dil için geçerli değildir. Bu bölümün ilerleyen kısımlarında bir örnek verilmiştir.

Sayfa 352
7.4 Tip Dönüşümleri 331
Çarpma operatörünün ikinci işleneninin varsayıldığını varsayalım.
olmak c ama çünkü bir anahtarlama hata o olarak yazılmış bir . Çünkü karma mod
Java'da ifadeler yasaldır, derleyici bunu bir hata olarak algılamaz. o
int işleneninin değerini , a , yüzmeye zorlamak için basitçe kod eklerdi .
Java'da karma mod ifadeleri yasal değilse, bu anahtarlama hatası
derleyici tarafından bir tür hatası olarak algılandı.
Karışık mod ifadeleri kullanıldığında hata algılaması azaldığından
İzin verilirse Ada, ifadelerde çok az sayıda karışık tip işlenene izin verir. O değil
bir ifadede tamsayı ve kayan nokta işlenenlerinin karıştırılmasına izin verir.
istisna: üs alma operatörü, ** , bir kayan nokta veya
ilk işlenen için bir tamsayı türü ve ikinci işlenen için bir tamsayı türü
ve. Ada, genellikle aşağıdakilerle ilgili olan birkaç tür işlenen türü karıştırmaya izin verir.
alt aralık türleri. Java kodu örneği Ada'da yazılmış olsaydı,
A : Tamsayı;
B, C, D : Şamandıra;
. . .
C := B * A;
o zaman Ada derleyicisi ifadeyi hatalı bulur, çünkü Float
ve Tamsayı işlenenleri * operatörü için karıştırılamaz .
ML ve F#, ifadelerde işlenenleri zorlamaz. Herhangi bir gerekli kon-
sürümler açık olmalıdır. Bu, aynı yüksek düzeyde güvenilirlik ile sonuçlanır
Ada tarafından sağlanan ifadeler.
Diğer yaygın dillerin çoğunda, herhangi bir kısıtlama yoktur.
karma modlu aritmetik ifadeler.
C tabanlı diller daha küçüktür tamsayı türleri var int
tip. Java'da bunlar bayt ve kısadır . Tüm bu türlerin işlenenleri
coerced int herhangi operatör onlara her uygulandığında neredeyse. Yani, süre
veriler bu tür değişkenlerde saklanabilir, daha önce manipüle edilemez
daha büyük bir türe dönüştürme. Örneğin, aşağıdaki Java kodunu göz önünde bulundurun:
bayt a, b, c;
. . .
a = b + c;
Değerleri b ve c ile zorlanırlar int ve int ilaveli gerçekleştirilir.
Ardından, toplam bayta dönüştürülür ve bir . Büyük boyutu göz önüne alındığında
Çağdaş bilgisayarların anıları, bayt kullanmak için çok az teşvik var ve
kısa , çok sayıda saklanması gerekmedikçe.
7.4.2 Açık Tip Dönüşüm
Çoğu dil, her ikisi de açık dönüşümler yapmak için bazı yetenekler sağlar.
genişleme ve daralma. Bazı durumlarda, uyarı mesajları şu durumlarda üretilir:
açık bir daraltma dönüşümü, değerinde önemli bir değişiklikle sonuçlanır.
dönüştürülmekte olan nesne.

Sayfa 353
332
Bölüm 7 İfadeler ve Atama İfadeleri
C-tabanlı dillerde, açık tip dönüşümler denir.
yayınlar . Bir döküm belirtmek için, istenen tür parantez içine alınır
dönüştürülecek ifadeden hemen önce, olduğu gibi
(int) açı
Tür adının etrafındaki parantezlerin nedenlerinden biri
bu dönüşümlerde, bu dillerden ilki olan C,
long int gibi birkaç iki kelimelik tür adı .
ML ve F#'da yayınlar, işlev çağrılarının sözdizimine sahiptir. İçin
örneğin, F#'da aşağıdakilere sahip olabiliriz:
yüzer (toplam)
7.4.3 İfadelerdeki Hatalar
İfade değerlendirmesi sırasında bir takım hatalar meydana gelebilir. Eğer
dil, statik veya dinamik tip denetimi gerektirir,
o zaman işlenen türü hataları oluşamaz. Oluşabilecek hatalar
ifadelerdeki işlenenlerin zorlamaları nedeniyle zaten
tartışıldı. Diğer hata türleri, sınırlamalardan kaynaklanmaktadır.
bilgisayar aritmetiği ve aritmetiğin doğal sınırlamaları.
En yaygın hata, bir işlemin sonucu
olması gerektiği yerde bellek hücresinde temsil edilemez.
saklanabilir. Buna bağlı olarak taşma veya yetersiz akış denir .
sonucun çok büyük veya çok küçük olup olmadığı. Bir sınırlama
aritmetik, sıfıra bölmeye izin verilmemesidir. Tabii ki,
matematiksel olarak izin verilmemesi, bir pro-
Bunu yapmaya çalışmaktan gram.
Kayan noktalı taşma, taşma ve sıfıra bölme örnekleridir.
bazen istisnalar olarak adlandırılan çalışma zamanı hataları . Dil olanakları
programların istisnaları algılamasına ve bunlarla ilgilenmesine izin verme, Bölüm 14'te tartışılmaktadır.
7.5 İlişkisel ve Boole İfadeleri
Aritmetik ifadelere ek olarak, programlama dilleri ilişkilendirmeyi destekler.
tional ve Boole ifadeleri.
7.5.1 İlişkisel İfadeler
Bir ilişkisel operatör iki çalıştırılmasından değerlerini karşılaştırır bir operatördür
ve İlişkisel bir ifadenin iki işleneni ve bir ilişkisel işleci vardır.
İlişkisel bir ifadenin değeri Boolean'dır, ancak Boolean bir
dilde bulunan tür. İlişkisel operatörler genellikle aşırı yüklenir
çeşitli türler için. Gerçeği veya yanlışlığı belirleyen işlem
tarih notu
Daha uç bir örnek olarak
tehlikeleri ve maliyetleri hakkında
çok fazla zorlama, düşün
PL/I'nin esnekliğe ulaşma çabaları
ifadelerde yetenek. PL/I'de,
bir karakter dizisi değişkeni
bir tamsayı ile birleştirilebilir
ifade. Çalışma zamanında,
dize sayısal olarak taranır
değer. değer gerçekleşirse
bir ondalık nokta içerir,
değerin olduğu varsayılır
kayan nokta türü, diğer
işlenen kayan-
noktası ve elde edilen işlem
kayan noktadır. bu zorlama
poliçe çok pahalı çünkü
hem tip kontrolü hem de con-
sürüm çalışma zamanında yapılmalıdır.
olasılığını da ortadan kaldırır.
programcı hatalarını tespit etme
ifadelerde, çünkü bir ikili
operatör bir işlemi birleştirebilir
ve bir işlenene sahip herhangi bir türden
hemen hemen her türden.

Sayfa 354
7.5 İlişkisel ve Boole İfadeleri 333
ilişkisel bir ifadenin değeri, işlenen türlerine bağlıdır. Yapabilir
tamsayı işlenenler için basit veya karakter için karmaşık olun
dize işlenenleri. Tipik olarak, işlenenlerin türleri
ilişkisel operatörler için kullanılanlar sayısal türler, diziler ve sıralardır.
nal türleri.
Eşitlik için ilişkisel operatörlerin sözdizimi ve
eşitsizlik bazı programlama dilleri arasında farklılık gösterir. İçin
örneğin, eşitsizlik için C tabanlı diller != kullanır, Ada kullanır
/= , Lua ~= kullanır , Fortran 95+ .NE kullanır . veya <> ve ML ve F#
<> kullanın .
JavaScript ve PHP'nin iki ek ilişkisel operatörü vardır,
=== ve !== . Bunlar akrabalarına benzer, == ve != , ancak onların
operandlar zorlanmaktan kurtarılır. Örneğin, ifade
"7" == 7
JavaScript'te doğrudur, çünkü bir dize ve bir sayı bir dizinin işlenenleri olduğunda
ilişkisel operatör, dize bir sayıya zorlanır. Ancak,
"7" === 7
false, çünkü bu operatörün işlenenleri üzerinde herhangi bir zorlama yapılmaz.
Ruby, zorlamaları kullanan eşitlik ilişkisel operatörü için == kullanır ve
eql? zorlama olmadan eşitlik için. Ruby, === öğesini yalnızca When yan tümcesinde kullanır .
onun vaka olarak Bölüm 8'de açıklanmıştır açıklamada,.
İlişkisel operatörler her zaman aritmetikten daha düşük önceliğe sahiptir.
operatörler, böylece gibi ifadelerde
a + 1 > 2 * b
önce aritmetik ifadeler değerlendirilir.
7.5.2 Boole İfadeleri
Boole ifadeleri Boole değişkenleri, Boole sabitleri, ilişkisel
ifadeler ve Boole operatörleri. Operatörler genellikle aşağıdakileri içerir:
VE, VEYA ve DEĞİL işlemleri ve bazen özel VEYA ve eşdeğeri için
lence. Boole işleçleri genellikle yalnızca Boole işlenenlerini alır (Boole değişkeni
mümkünler, Boole değişmezleri veya ilişkisel ifadeler) ve Boole değerleri üretir.
Boole cebirlerinin matematiğinde OR ve AND operatörleri
eşit önceliğe sahiptir. Buna göre Ada'nın AND ve OR operatörleri
eşit önceliğe sahiptir. Ancak, C tabanlı diller daha yüksek bir ön
VE'ye OR'den daha fazla geçiş. Belki de bu temelsiz korelasyondan kaynaklanmıştır.
VE ile çarpma ve VEYA ile toplama, doğal olarak
AND öğesine daha yüksek öncelik atayın.
Çünkü aritmetik ifadeler ilişkisel ifadenin işlenenleri olabilir.
ve ilişkisel ifadeler, Boolean ifadelerinin işlenenleri olabilir,
tarih notu
Fortran I tasarımcılarının kullandığı
için İngilizce kısaltmalar
ilişkisel operatörler çünkü
> ve < sembolleri açık değildi
kart şu anda yumruk atıyor
Fortran I'in tasarımı (1950'lerin ortası).

Sayfa 355
334
Bölüm 7 İfadeler ve Atama İfadeleri
üç operatör kategorisi farklı öncelik seviyelerine yerleştirilmelidir,
birbirine göre.
aritmetik, ilişkisel ve Boole operatörlerinin önceliği
C tabanlı diller aşağıdaki gibidir:
C99'dan önceki C sürümleri, popüler zorunlu dil arasında tuhaftır.
Boole tipi ve dolayısıyla Boolean değerleri olmadığı için ölçüm yapar. Bunun yerine,
Boole değerlerini temsil etmek için sayısal değerler kullanılır. Boolean işlemi yerine
ands, skaler değişkenler (sayısal veya karakter) ve sabitler sıfır ile kullanılır
yanlış olarak kabul edilir ve sıfırdan farklı tüm değerler doğru olarak kabul edilir. Değerlendirme sonucu-
böyle bir ifade, yanlışsa 0 ve doğruysa 1 değerine sahip bir tamsayıdır. arit-
Metik ifadeler, C99 ve C++'daki Boole ifadeleri için de kullanılabilir.
C'nin ilişkisel ifade tasarımının tuhaf bir sonucu şudur:
ifade yasaldır:
a > b > c
En soldaki ilişkisel işleç ilk olarak değerlendirilir, çünkü ilişkisel işlem-
C'nin tor'ları ya 0 ya da 1 üreten birleştirici bırakılır.
c değişkeni ile eşleştirilir . Arasında bir karşılaştırma yoktur asla b ve c bunda
ifade.
Perl ve Ruby de dahil olmak üzere bazı diller, iki ikili dosya kümesi sağlar.
mantık operatörleri, && ve ve için AND ve || ve veya VEYA için. bir fark
arasında && ve ve (ve || ve ya ) yazıldığından versiyonları alt olması
öncelik. Ayrıca ve ve/ veya eşit önceliğe sahiptir, ancak && daha yüksek ön-
cedence daha || .
C tabanlı dillerin aritmetik olmayan operatörleri dahil edildiğinde,
40'tan fazla operatör ve en az 14 farklı öncelik seviyesi vardır.
Bu, operatörlerin koleksiyonlarının zenginliğinin açık bir kanıtıdır ve
bu dillerde ifadelerin karmaşıklığı mümkündür.
Okunabilirlik, bir dilin olduğu gibi bir Boolean türü içermesi gerektiğini belirtir.
Boolean ifadelerinde sayısal türleri kullanmak yerine Bölüm 6'da belirtilmiştir.
Boolean işlenenleri için sayısal türlerin kullanımında bazı hata algılamaları kayboluyor,
En yüksek
postfix ++ , --
tekli + , - , önek ++ , -- , !
* , / , %
ikili + , -
< , > , <= , >=
= , !=
&&
En düşük
||

Sayfa 356
7.6 Kısa Devre Değerlendirmesi 335
çünkü herhangi bir sayısal ifade, amaçlanmış olsun veya olmasın, yasal bir işlenendir.
Boole operatörü. Diğer zorunlu dillerde, Boole olmayan herhangi bir ifade
Boolean operatörünün işleneni olarak kullanıldığında hata olarak algılanır.
7.6 Kısa Devre Değerlendirmesi
Bir ifadenin kısa devre değerlendirmesi sonucun caydırıcı olduğu bir değerlendirmedir .
tüm işlenenleri ve/veya operatörleri değerlendirmeden mayınlı. Örneğin,
aritmetik ifadenin değeri
(13 * a) * (b / 13 - 1)
değerinden bağımsız olan (b / 13 - 1) , eğer bir olduğu 0 , çünkü 0 x = 0 için
herhangi bir x . Yani, bir olan 0 , değerlendirmek için gerek yoktur - (1 b / 13) ya da yerine
ikinci çarpma. Ancak, aritmetik ifadelerde bu kısayol
yürütme sırasında kolayca tespit edilemez, bu nedenle asla alınmaz.
Boole ifadesinin değeri
(a >= 0) && (b < 10)
a < 0 ise ikinci ilişkisel ifadeden bağımsızdır , çünkü ifade-
sion ( FALSE && ( b <10 )) olan, YANLIŞ tüm değerleri için b . Yani, bir 6 0 olduğunda, orada
değerlendirmek için bir ihtiyaç vardır , b , sabit 10 , ikinci ilişkisel ifade veya
&& çalışma. Aritmetik ifadelerden farklı olarak, bu kısayol,
yürütme sırasında kolayca keşfedilebilir.
Kısa devre olmayan değerlendirme ile olası bir sorunu göstermek için
Boolean ifadeleri, Java'nın kısa devre değerlendirmesi kullanmadığını varsayalım. Bir masa
while ifadesi kullanılarak arama döngüsü yazılabilir . Basit bir versiyonu
listlen öğelerine sahip olan list varsayarsak, böyle bir arama için Java kodu ,
aranacak dizidir ve anahtar aranan değerdir,
indeks = 0;
while ((index < listlen) && (list[index] != key))
indeks = indeks + 1;
Değerlendirme kısa devre değilse, Boolean'daki her iki ilişkisel ifade de
ifadesi ise ifadesinin değeri ne olursa olsun, değerlendirilir
ilk. Bu nedenle, anahtar listede değilse , program bir alt simge ile sona erecektir.
kapsam dışı istisna. Sahip aynı yineleme indeksi == listlen irade
liste olduğundan dizin oluşturma hatasına neden olan referans listesi[listlen]
bir üst sınır alt simge değeri olarak listlen-1'e sahip olduğu bildirildi .
Bir dil, Boolean ifadelerinin kısa devre değerlendirmesini sağlıyorsa ve
kullanılır, bu bir sorun değildir. Önceki örnekte, bir kısa devre değerlendirmesi
ation şeması AND operatörünün ilk işlenenini değerlendirir, ancak
ilk işlenen yanlışsa ikinci işleneni atlar.

Sayfa 357
336
Bölüm 7 İfadeler ve Atama İfadeleri
Boolean ifadelerinin kısa devre değerlendirmelerini sağlayan bir dil
ve ayrıca yan etkileri olan ifadelerde ince hataların oluşmasını sağlar. Sanmak
kısa devre değerlendirmesinin bir ifadede ve ifadenin bir kısmında kullanıldığını
yan etki içerenler değerlendirilmez; o zaman yan etki ortaya çıkar
sadece tüm ifadenin tam değerlendirmelerinde. Eğer program doğruluğu
yan etkiye bağlıdır, kısa devre değerlendirmesi ciddi bir hataya neden olabilir.
Örneğin, Java ifadesini düşünün
(a > b) || ((b++) / 3)
Bu ifadede sadece b değiştirilir (ikinci aritmetik ifadede)
ne zaman bir <= b . Programcı b'nin her seferinde değiştirileceğini varsayarsa
bu ifade yürütme sırasında değerlendirilir (ve programın doğruluğu
buna bağlıdır), program başarısız olur.
Ada, programcının Bool'un kısa devre değerlendirmesini belirlemesine izin verir.
iki kelimelik operatörleri kullanarak AND ve OR operatörlerini ve ardından ve
ya da başka . Ada ayrıca kısa devre olmayan operatörlere sahiptir ve ve veya .
C tabanlı dillerde, normal AND ve OR operatörleri, && ve || ,
sırasıyla kısa devredir. Ancak, bu diller ayrıca bit düzeyinde VE
ve VEYA operatörleri, & ve | , sırasıyla, Boolean değerli üzerinde kullanılabilecek
işlenenler ve kısa devre değildir. Tabii ki, bitsel operatörler yalnızca
tüm işlenenler şu şekilde sınırlandırılmışsa, olağan Boole operatörlerine eşdeğerdir.
ya 0 (yanlış için) ya da 1 (doğru için).
Ruby, Perl, ML, F# ve Python'un tüm mantıksal operatörleri kısadır.
devre değerlendirildi.
Ada'da hem kısa devre hem de sıradan operatörlerin dahil edilmesi
açıkça en iyi tasarım, çünkü programcıya esneklik sağlar
olduğu herhangi bir Boole ifadesi için kısa devre değerlendirmesi seçme
uygun.
7.7 Atama İfadeleri
Daha önce de belirttiğimiz gibi, atama ifadesi merkezi ifadelerden biridir.
zorunlu dillerde yapılar. mekanizmasını sağlar.
kullanıcı, değerlerin bağlarını değişkenlere dinamik olarak değiştirebilir. takipte-
bölümünde, en basit atama şekli tartışılmıştır. sonraki bölümler
çeşitli alternatifleri açıklayın.
7.7.1 Basit Atamalar
Şu anda kullanılmakta olan neredeyse tüm programlama dilleri için eşittir işaretini kullanır.
atama operatörü Bunların tümü, farklı bir şey kullanmalıdır.
eşitlik ilişkisel işlecinin kendileriyle karıştırılmaması için eşittir işareti
atama operatörü.

Sayfa 358
ALGOL 60 , atama operatörü olarak := kullanımına öncülük etmiştir.
atamanın eşitlikle karıştırılmasını önler. Ada da bu atamayı kullanır
Şebeke.
Ödevlerin bir dilde nasıl kullanıldığına ilişkin tasarım seçenekleri çeşitlilik göstermiştir.
yaygın olarak. Fortran ve Ada gibi bazı dillerde bir ödev görünebilir.
yalnızca bağımsız bir ifade olarak ve hedef, tek bir
değişken. Ancak birçok alternatif var.
7.7.2 Koşullu Hedefler
Perl, atama ifadelerinde koşullu hedeflere izin verir. Örneğin, düşünün
($bayrak ? $say1 : $say2) = 0;
hangi eşdeğerdir
if ($bayrak) {
$say1 = 0;
} başka {
$say2 = 0;
}
7.7.3 Bileşik Atama Operatörleri
Bir bileşik atama operatör a belirten bir kısa yöntemidir
yaygın olarak ihtiyaç duyulan atama şekli. Yapılabilecek atama şekli
Bu teknikle kısaltılan hedef değişkeni şu şekilde de görünür:
sağ taraftaki ifadedeki ilk işlenen, olduğu gibi
a = a + b
ALGOL 68 tarafından tanıtılan bileşik atama operatörleri,
daha sonra C tarafından biraz farklı bir biçimde benimsenmiştir ve diğer C-tabanlı
dillerin yanı sıra Perl, JavaScript, Python ve Ruby. Bunların sözdizimi
atama operatörleri, istenen ikili operatörün =
Şebeke. Örneğin,
toplam += değer;
eşdeğerdir
toplam = toplam + değer;
Bileşik atama işleçlerini destekleyen dillerin sürümleri vardır
ikili operatörlerinin çoğu için.
7.7 Atama İfadeleri 337

Sayfa 359
338
Bölüm 7 İfadeler ve Atama İfadeleri
7.7.4 Tekli Atama Operatörleri
C-tabanlı diller, Perl ve JavaScript, iki özel tekli aritmetik içerir.
aslında kısaltılmış atamalar olan metrik operatörler. birleştirirler
atama ile artırma ve eksiltme işlemleri. operatörler ++
artış için ve –– azalma için, ifadelerde veya
bağımsız tek operatör atama ifadeleri oluşturur. görünebilirler
ya önek operatörleri olarak, yani işlenenlerden önce gelirler ya da
postfix operatörleri, işlenenleri takip ettikleri anlamına gelir. ödevde
Beyan
toplam = ++ sayı;
count değeri 1 artırılır ve ardından toplama atanır . Bu opera-
olarak da ifade edilebilir
say = say + 1;
toplam = sayı;
Aynı operatör, aşağıdaki gibi bir postfix operatörü olarak kullanılıyorsa
toplam = say ++;
değerinin atanması sayımı için toplamı önce gelirse; sonra sayı artar
bahsetti. Etki, iki ifadeninkiyle aynıdır.
toplam = sayı;
say = say + 1;
Tam bir sayı oluşturmak için tekli artış operatörünün kullanımına bir örnek
atama ifadesi
saymak ++;
hangi sadece artışlar sayılır . Görev gibi görünmüyor ama
kesinlikle biridir. Bu ifadeye eşdeğerdir
say = say + 1;
Aynı işlenene iki birli operatör uygulandığında, ilişkilendirme
sağdan sola. örneğin,
- saymak ++
count önce artırılır ve sonra reddedilir. Yani, eşdeğerdir
- (saymak ++)

Sayfa 360
7.7 Atama İfadeleri 339
ziyade
(- saymak) ++
7.7.5 İfade Olarak Atama
C-tabanlı dillerde, Perl ve JavaScript'te, atama ifadesi pro-
hedefe atanan değerle aynı olan bir sonuç üretir. Yapabilir
bu nedenle bir ifade olarak ve diğer ifadelerde işlenen olarak kullanılabilir. Bu
tasarım, atama operatörüne diğer herhangi bir ikili operatör gibi davranır,
bunun dışında, sol işlenenini değiştirmenin yan etkisi vardır. örneğin,
C, gibi ifadeler yazmak yaygındır
while ((ch = getchar()) != EOF) { ... }
Bu ifadede, standart girdi dosyasındaki bir sonraki karakter, genellikle
klavye, getchar ile alınır ve ch değişkenine atanır . Sonuç,
veya atanan değer, daha sonra sabit EOF ile karşılaştırılır . Eğer ch eşit değildir
için EOF , bileşik deyim {...} yürütülür. Unutmayın ki atama-
olarak atamayı destekleyen dillerde parantez içine alınmalıdır.
ifadesi, atama operatörünün önceliği,
ilişkisel operatörler. Parantezler olmadan, yeni karakter
İlk önce EOF ile karşılaştırıldı . Ardından, bu karşılaştırmanın sonucu, 0 veya 1 ,
ch'ye atanır .
Atama ifadelerinin işlenen olmasına izin vermenin dezavantajı
ifadeler, başka bir tür ifade yan etkisi sağlamasıdır. Bu
yan etki türü, okunması zor ve eksik ifadelere yol açabilir.
durmak. Herhangi bir yan etkisi olan bir ifadenin bu dezavantajı vardır. Bu tür bir
ifade, matematikte bir ifade olan bir ifade olarak okunamaz.
bir değerin ifadesi, ancak yalnızca tek bir yürütme sırasına sahip talimatların bir listesi olarak.
Örneğin, ifade
a = b + (c = d / b) - 1
talimatları belirtir
d / b'yi c'ye ata
b + c'yi sıcaklığa ata
Sıcaklık - 1'i a'ya ata
Atama operatörünün diğer ikili işlemler gibi ele alındığını unutmayın.
tor gibi çoklu hedef atamalarının etkisine izin verir.
toplam = sayı = 0;
hangi sayıma ilk önce sıfır atanır ve ardından sayım değeri atanır
toplam. Bu çoklu hedef atama biçimi Python'da da yasaldır.

Sayfa 361
340
Bölüm 7 İfadeler ve Atama İfadeleri
Atama işleminin C tasarımında hata algılama kaybı var.
sık sık program hatalarına yol açan durum. Özellikle, yazarsak
Eğer (x = y) ...
onun yerine
eğer (x == y) ...
kolay yapılan bir hatadır, bilgisayar tarafından hata olarak algılanamaz.
kazık. İlişkisel bir ifadeyi test etmek yerine, atanan değer
x test edilir (bu durumda, bu ifadeye ulaşan y'nin değeridir ). Bu
aslında iki tasarım kararının bir sonucu: atamanın bir
sıradan ikili operatör ve çok benzer iki operatör kullanarak, = ve = =,
tamamen farklı anlamlara sahiptir. Bu, güvenlik tanımının başka bir örneğidir.
C ve C++ programlarının özellikleri. Java ve C#'ın yalnızca boole değerine izin verdiğini unutmayın.
Onların ifadeler eğer ifadeleri, bu sorunu izin vermeme.
7.7.6 Çoklu Atamalar
Perl, Ruby ve Lua dahil olmak üzere birçok yeni programlama dili,
çoklu hedef, çoklu kaynak atama ifadeleri. Örneğin, Perl'de
biri yazabilir
($birinci, $ikinci, $üçüncü) = (20, 40, 60);
Semantik olmasıdır 20 atanan ilk, $ , 40 atanır
için $ saniyede ve 60 atanan $ üçüncü . iki değer ise
değişkenler değiştirilmelidir, bu tek bir
olduğu gibi atama
($birinci, $ikinci) = ($ikinci, $birinci);
Bu, $first ve $second değerlerini doğru bir şekilde değiştirir ,
geçici bir değişken kullanılmadan (en az bir tane oluşturulmuş ve
programcı tarafından yönetilir).
Ruby'nin çoklu atamasının en basit biçiminin sözdizimi
sol ve sağ taraflar dışında Perl'inkine benzer
parantez içinde değildir. Ayrıca, Ruby birkaç tane daha ayrıntılı içerir
burada tartışılmayan çoklu atama sürümleri.
7.7.7 Fonksiyonel Programlamada Atama
Diller
Saf işlevsel dillerde kullanılan tüm tanımlayıcılar ve bazıları
diğer işlevsel dillerde kullanılanlardan sadece val-
ues. Bu nedenle değerleri asla değişmez. Örneğin, ML'de,
tarih notu
PDP-11 bilgisayarı, açık
hangi C ilk kez uygulandı,
otomatik artış ve otomatik-
adresleme modlarını azaltma,
donanım sürümleri olan
artış ve azalma
C operatörleri olduklarında
dizi indeksleri olarak kullanılır. Biri olabilir
bundan tahmin et tasarım
Bu C operatörlerinin
PDP-11'in tasarımı hakkında
mimari. Bu tahmin
yanlış olabilir, çünkü
C operatörleri miras alındı
olan B dilinden
ilkinden önce tasarlandı
PDP-11.

Sayfa 362
Özet 341
isimler , formu örneklenmiş olan val bildirimi ile değerlere bağlıdır.
aşağıdakilerde:
val maliyet = miktar * fiyat;
Eğer maliyeti bir sonraki sol tarafında görünen val beyanı, o Beyannameler-
ile hiçbir ilişkisi olmayan maliyet adının yeni bir sürümünü oluşturur.
daha sonra gizlenen önceki sürüm.
F#, let ayrılmış sözcüğü kullanan biraz benzer bir bildirime sahiptir .
F # 'ın arasındaki fark let , ML ve en val yani let , yeni kapsamı oluşturur
oysa val yapmaz. Aslında, val bildirimleri genellikle let con-
ML'deki yapılar. Hem let hem de val , Bölüm 15'te daha ayrıntılı olarak tartışılmaktadır.
7.8 Karma Mod Atama
Karışık mod ifadeleri Bölüm 7.4.1'de tartışıldı. Sıklıkla, atama-
ment ifadeleri de karma moddur. Tasarım sorusu şudur: Tip
ifadenin, atanan değişkenin türüyle aynı olması gerekir,
veya bazı tür uyumsuzluğu durumlarında zorlama kullanılabilir mi?
Fortran, C, C++ ve Perl, karma mod ataması için zorlama kurallarını kullanır
karma mod ifadeleri için kullandıklarına benzer; yani, birçoğu
olası tip karışımlar yasaldır ve zorlama serbestçe uygulanır. 7 Ada değil
karma mod atamasına izin verir.
C++'dan net bir şekilde ayrılarak Java ve C# karma mod atamasına izin verir
sadece gerekli zorlama genişliyorsa. 8 Böylece, bir int değeri atanabilir
bir kayan değişken, ancak tersi değil. Olası karışıklığın yarısına izin verilmemesi
mod atamaları, Java'nın güvenilirliğini artırmanın basit ama etkili bir yoludur
ve C#, C ve C++ ile ilgili.
Tabii ki, atamaların sadece kullanıldığı işlevsel dillerde
ad değerleri için karma mod ataması diye bir şey yoktur.
ÖZET
İfadeler sabitlerden, değişkenlerden, parantezlerden, işlev çağrılarından ve
operatörler. Atama ifadeleri, hedef değişkenleri, atama işlemlerini içerir.
tor ve ifadeler.
7. Python ve Ruby'de türlerin değişkenlerle değil nesnelerle ilişkilendirildiğini unutmayın, bu nedenle
bu dillerde karışık mod atama gibi bir şey.
8. oldukça doğru değil: varsayılan olarak derleyici tipi atar bir tamsayı değişmezi, varsa int olduğu
bir char , bayt veya kısa değişkene atanır ve değişmez değer, türün aralığındadır.
değişken, int değeri, daraltma dönüşümünde değişkenin türüne zorlanır. Bu
dönüştürmeyi daraltmak bir hataya neden olamaz.

Sayfa 363
342
Bölüm 7 İfadeler ve Atama İfadeleri
Bir ifadenin semantiği büyük ölçüde şu sıraya göre belirlenir:
operatörlerin değerlendirilmesi. Operatörler için ilişkilendirme ve öncelik kuralları
bir dilin ifadelerinde operatör değerlendirme sırasını belirler
bu ifadelerde. Fonksiyonel tarafta ise işlenen değerlendirme sırası önemlidir
etkileri mümkündür. Tür dönüşümleri genişleyebilir veya daraltabilir. Bazı
daraltma dönüşümleri hatalı değerler üretir. Örtülü tür dönüşümleri,
veya zorlamalar, hataları ortadan kaldırsalar da, ifadelerde yaygındır.
Tip kontrolünün algılama avantajı, böylece güvenilirliği düşürür.
Atama beyanları, aşağıdakiler de dahil olmak üzere çok çeşitli biçimlerde ortaya çıkmıştır:
koşullu hedefler, atama operatörleri ve liste atamaları.
İNCELEME SORULARI
1. Operatör önceliğini ve operatör ilişkilendirilebilirliğini tanımlayın .
2. Üçlü operatör nedir?
3. Ön ek operatörü nedir?
4. Hangi operatör genellikle doğru ilişkilendirmeye sahiptir?
5. İlişkisel olmayan operatör nedir?
6. APL tarafından hangi ilişkilendirme kuralları kullanılır?
7. Operatörlerin uygulama biçimleri arasındaki fark nedir?
C++ ve Ruby?
8. Fonksiyonel yan etkiyi tanımlayın .
9. Zorlama nedir?
10. Koşullu ifade nedir?
11. Aşırı yüklenmiş operatör nedir?
12. Daraltma ve genişletme dönüşümlerini tanımlayın .
13. JavaScript'te == ve === arasındaki fark nedir?
14. Karma mod ifadesi nedir?
15. Referans şeffaflığı nedir?
16. Referans şeffaflığının avantajları nelerdir?
17. İşlenen değerlendirme sırası işlevsel tarafla nasıl etkileşime girer?
Etkileri?
18. Kısa devre değerlendirmesi nedir?
19. Boolean'ın her zaman kısa devre değerlendirmesini yapan bir dil adlandırın
ifade. Bunu asla yapmayan bir isim söyleyin. Pro-
gramer seçmesine izin verilir.
20. C, ilişkisel ve Boolean ifadeleri nasıl destekler?
21. Bileşik atama operatörünün amacı nedir?
22. C'nin tekli aritmetik operatörlerinin ilişkiselliği nedir?

Sayfa 364
Problem Seti 343
23. Atama operatörüne şu şekilde davranmanın olası bir dezavantajı nedir?
aritmetik bir operatör olsaydı?
24. Hangi iki dil birden fazla atama içerir?
25. Ada'da hangi karma mod atamalarına izin verilir?
26. Java'da hangi karma mod atamalarına izin verilir?
27. Makine öğreniminde hangi karma mod atamalarına izin verilir?
28. Oyuncu kadrosu nedir?
PROBLEM SETİ
1. Derleyicinin bir dosyadaki tür farklılıklarını yok saymasını ne zaman isteyebilirsiniz?
ifade?
2. Karma modlu aritmete izin vermenin lehinde ve aleyhinde kendi argümanlarınızı belirtin.
metik ifadeler.
3. Favori dizinizde aşırı yüklenen operatörlerin ortadan kaldırılmasını düşünüyor musunuz?
dil işe yarar mı? Neden veya neden olmasın?
4. Tüm operatör öncelik kurallarını ortadan kaldırmak ve
ifadelerde istenen önceliği göstermek için parantez gerekiyor mu? Neden
ya da neden olmasın?
5. C'nin atama işlemleri (örneğin, += ) diğer
diller (zaten bunlara sahip olmayan)? Neden veya neden olmasın?
6. C'nin tek işlenenli atama formları (örneğin, ++count )
(zaten sahip olmayan) diğer dillere dahil edilebilir mi? neden veya
neden?
7. Ekleme operatörünün bir programlama lan-
guage değişmeli olmaz.
8. Ekleme operatörünün bir programlama lan-
guage birleştirici olmaz.
9. Aşağıdaki ilişkilendirme ve öncelik kurallarını varsayın:
ifade:
Öncelik
En yüksek
*, / , değil
+, –, & , mod
- (tek)
=, /=, <, <=, >=, >
ve
En düşük
veya , xor
çağrışım
Soldan sağa

Sayfa 365
344
Bölüm 7 İfadeler ve Atama İfadeleri
Aşağıdaki ifadelerin değerlendirme sırasını parantez içinde gösteriniz.
tüm alt ifadeleri boyutlandırma ve sağ parantez üzerine bir üst simge yerleştirme
sipariş belirtmek için sis. Örneğin, ifade için
a + b * c + d
değerlendirme sırası olarak temsil edilecektir
((a + (b * c) 1 ) 2 + d) 3
a. a * b - 1 + c
B. a * (b - 1) / c mod d
C. (a - b) / c & (d * e / a - 3)
D. -a veya c = d ve e
e. a > b xor c veya d <= 17
F. -a + b
10. Varsayımsal olarak Problem 9'daki ifadelerin değerlendirme sırasını gösterin.
öncelik kuralı yoktur ve tüm operatörler sağdan sola ilişkilenir.
11. Öncelik ve ilişkilendirme kurallarının bir BNF tanımını yazın
Problem 9'daki ifadeler için tanımlanmıştır.
a,b,c,d ve e adları .
12. Problem 11'in gramerini kullanarak, ifadeler için ayrıştırma ağaçları çizin.
9. Sorunun
13. fun fonksiyonu şu şekilde tanımlansın
int eğlence( int *k) {
*k += 4;
dönüş 3 * (*k) - 1;
}
Bir programda eğlencenin aşağıdaki gibi kullanıldığını varsayalım:
geçersiz ana() {
int i = 10, j = 10, toplam1, toplam2;
toplam1 = (i / 2) + eğlence(&i);
toplam2 = eğlence(&j) + (j / 2);
}
Değerleri nelerdir sum1 ve sum2
a. ifadelerdeki işlenenler soldan sağa doğru değerlendirilirse?
B. ifadelerdeki işlenenler sağdan sola doğru değerlendirilirse?

Sayfa 366
Programlama Alıştırmaları 345
14. Operatör önceliğine karşı (veya onun için) birincil argümanınız nedir?
APL kuralları?
15. C'deki fonksiyonel yan etkileri ortadan kaldırmanın neden zor olduğunu açıklayın.
16. Seçtiğiniz bazı diller için operatör sembollerinin bir listesini yapın
tüm operatör aşırı yüklemesini ortadan kaldırmak için kullanılabilir.
17. Daralan açık tip dönüşümlerinin iki lan-
Bildiğiniz göstergeler, dönüştürülen bir değer kaybolduğunda hata mesajları verir.
kullanışlılık
18. C veya C++ için optimize edici bir derleyicinin
Boole ifadesinde alt ifadelerin sırası? Neden veya neden olmasın?
19. Ada için Problem 17'deki soruyu cevaplayın.
20. Aşağıdaki C programını düşünün:
int eğlence( int *i) {
*i += 5;
dönüş 4;
}
geçersiz ana() {
int x = 3;
x = x + eğlence(&x);
}
Varsayalım, main'deki atama ifadesinden sonra x'in değeri nedir?
a. işlenenler soldan sağa değerlendirilir.
B. işlenenler sağdan sola değerlendirilir.
21. Java neden ifadelerdeki işlenenlerin tümünün
soldan sağa sıralama?
22. Bir dilin zorlama kurallarının hata tespitini nasıl etkilediğini açıklayın.
PROGRAMLAMAALIŞTIRMALAR
1. Problem 13'te (Problem Setinde) verilen kodu bazı sistemlerde çalıştırın.
bu, sum1 ve sum2 değerlerini belirlemek için C'yi destekler . açıklayın
Sonuçlar.
2. Programlama Alıştırma 1'in programını C++, Java ve C# ile yeniden yazın,
çalıştırın ve sonuçları karşılaştırın.
3. En sevdiğiniz dilde aşağıdakileri belirleyen bir test programı yazın ve
aritmetiğinin ve Boolean'ın önceliğini ve ilişkilendirilebilirliğini verir
operatörler.

Sayfa 367
346
Bölüm 7 İfadeler ve Atama İfadeleri
4. Java'nın işlenen değerlendirmesi için kuralını ortaya koyan bir Java programı yazın
işlenenlerden biri bir yöntem çağrısı olduğunda sipariş verin.
5. Programlama Egzersizi 5'i C++ ile tekrarlayın.
6. Programlama Egzersizi 6'yı C# ile tekrarlayın.
7. C++, Java veya C# dillerinden birinin sırasını gösteren bir program yazın.
Bir yönteme gerçek parametreler olarak kullanılan ifadelerin değerlendirilmesi.
8. Aşağıdaki ifadelere sahip bir C programı yazın:
int a, b;
a = 10;
b = bir + eğlence();
printf("Sağdaki fonksiyon çağrısı ile ");
printf(" b'dir: %d\n", b);
a = 10;
b = eğlence() + a;
printf("Soldaki fonksiyon çağrısı ile ");
printf(" b'dir: %d\n", b);
ve tanımlamak eğlenceli 10 üzeri eklemek için bir . Sonuçları açıklayın.
9. Java, C++ veya C# dilinde çok sayıda işlem gerçekleştiren bir program yazın.
kayan noktalı işlemler ve eşit sayıda tamsayılı işlemler
ve gerekli süreyi karşılaştırın.

Sayfa 368
347
8.1 Giriş
8.2 Seçim Açıklamaları
8.3 Yinelemeli İfadeler
8.4 Koşulsuz Dallanma
8.5 Korunan Komutlar
8.6 Sonuçlar
8
İfade Düzeyi
Kontrol Yapıları

Sayfa 369
348
Bölüm 8 İfade Düzeyinde Kontrol Yapıları
T bir program incelenebilir o, kontrol veya yürütme dizisinin akış
birkaç seviye. Bölüm 7'de, ifadeler içindeki kontrol akışı,
operatör birlikteliği ve öncelik kuralları tarafından yönetilen, tartışıldı. saat
en yüksek seviye, aşağıda tartışılan program birimleri arasındaki kontrol akışıdır.
9. ve 13. Bölümler. Bu iki uç nokta arasındaki önemli konu,
Bu bölümün konusu olan ifadeler arasındaki kontrol.
Kontrol ifadelerinin evrimine genel bir bakış vererek başlıyoruz. Bu
konuyu, her ikisi için de seçim ifadelerinin kapsamlı bir incelemesi izler.
iki yönlü ve çoklu seçim için olanlar. Daha sonra, döngü çeşitliliğini tartışacağız
Programlama dillerinde geliştirilen ve kullanılan ifadeler. Sonra biz
koşulsuz dal ifadeleriyle ilgili sorunlara kısa bir göz atın.
Son olarak, korunan komut kontrol deyimlerini açıklıyoruz.
8.1 Giriş
Zorunlu dil programlarındaki hesaplamalar, değerlendirme ile gerçekleştirilir.
ifadeler oluşturma ve elde edilen değerleri değişkenlere atama. Ancak, orada
tamamen atama ifadelerinden oluşan birkaç faydalı programdır. En azından
hesaplamaları yapmak için iki ek dilsel mekanizma gereklidir
esnek ve güçlü programlarda: alternatifler arasından seçim yapmanın bazı yolları
kontrol akış yolları (ifade yürütmenin) ve buna neden olmanın bazı yolları
ifadelerin veya ifade dizilerinin tekrar tekrar yürütülmesi. ifadeler
bu tür yetenekleri sağlamak, kontrol ifadeleri olarak adlandırılır .
Fonksiyonel programlama dillerinde hesaplamalar gerçekleştirilir
ifadeleri ve işlevleri değerlendirerek. Ayrıca, yürütme akışı
ifadeler ve işlevler arasında diğer ifadeler tarafından kontrol edilir ve
işlevleri, bazıları aşağıdaki kontrol ifadelerine benzer olsa da
zorunlu diller.
İlk başarılı programlama dili olan For-
tran, aslında IBM 704'ün mimarları tarafından tasarlandı.
makine dili talimatlarıyla ilgiliydi, bu nedenle yetenekleri daha fazlaydı.
dil tasarımından ziyade öğretim tasarımının sonucudur. O zamanlar azdı
programlamanın zorluğu hakkında bilinir ve sonuç olarak kontrol durumu-
Fortran'ın 1950'lerin ortalarındaki kararlarının tamamen kabul edilebilir olduğu düşünülüyordu. İle
Ancak günümüz standartları tamamen yetersiz kabul ediliyor.
Kontrol ifadeleri için çok fazla araştırma ve tartışma yapıldı.
1960'ların ortaları ile 1970'lerin ortaları arasındaki 10 yılda. Biri öncelikli
Bu çabaların sonuçları, tek bir kontrol durumu olmasına rağmen-
ment (seçilebilir bir git), tasarlanmış bir dil minimal yeterlidir değil
goto eklemek için yalnızca az sayıda farklı kontrol ifadesi gerekir.
Aslında akış şemaları ile ifade edilebilen tüm algoritmaların
sadece iki kontrol ifadesi ile bir programlama dilinde kodlanabilir:
biri iki kontrol akış yolu arasında seçim yapmak için, diğeri mantıksal olarak bağlantı için
Trolled yinelemeler (Böhm ve Jacopini, 1966). Bunun önemli bir sonucu
koşulsuz dal ifadesi gereksizdir - potansiyel olarak yararlıdır, ancak

Sayfa 370
8.1 Giriş 349
gereksiz. Bu gerçek, uyumsuz kullanmanın pratik sorunlarıyla birleştiğinde,
Ditional dalları veya gotos, olduğu gibi goto hakkında büyük bir tartışmaya yol açtı.
Bölüm 8.4'te tartışılacaktır.
Programcılar, kontrol üzerine teorik araştırmaların sonuçlarını daha az önemser
yazılabilirlik ve okunabilirlik hakkında yaptıklarından daha fazla ifadeler. olan tüm diller
yaygın olarak kullanılan ikisinden daha fazla kontrol ifadesi içerir.
minimum düzeyde gereklidir, çünkü yazılabilirlik daha büyük bir sayı ile artırılır ve
daha geniş çeşitlilikte kontrol ifadeleri. Örneğin, bunu gerektirmek yerine
tüm döngüler için mantıksal olarak kontrol edilen bir döngü ifadesinin kullanılması, yazmak daha kolaydır
döngüler oluşturmak için sayaç kontrollü bir döngü ifadesi kullanılabildiğinde programlar
doğal olarak bir sayaç tarafından kontrol edilir. kısıtlayan birincil faktör
bir dildeki kontrol deyimlerinin sayısı okunabilirliktir, çünkü varlığı
çok sayıda ifade formunun, program okuyucularının bir
daha büyük dil. Çok az kişinin görece bir ifadenin tüm ifadelerini öğrendiğini hatırlayın.
büyük dil; bunun yerine kullanmayı seçtikleri alt kümeyi öğrenirler; bu genellikle
programı yazan programcı tarafından kullanılandan farklı bir alt küme
okumaya çalışıyorlar. Öte yandan, çok az sayıda kontrol ifadesi
goto gibi daha düşük seviyeli ifadelerin kullanılmasını gerektirir ve bu da
programlar daha az okunabilir.
sağlamak için en iyi kontrol ifadeleri koleksiyonuna ilişkin soru
gerekli yetenekler ve istenen yazılabilirlik geniş çapta tartışılmıştır. Bu
aslında bir dilin ne kadar genişletilmesi gerektiği sorusu
basitliği, boyutu ve okunabilirliği pahasına yazılabilirliği.
Bir kontrol yapısı , bir kontrol ifadesi ve ifadelerin toplanmasıdır.
kimin yürütmesini kontrol ediyor.
Tüm seçimle ilgili olan tek bir tasarım sorunu vardır ve
yineleme kontrol ifadeleri: Kontrol yapısının birden fazla girişi olmalı mı?
Tüm seçim ve yineleme yapıları, kod bölümlerinin yürütülmesini kontrol eder,
ve soru, bu kod bölümlerinin yürütülmesinin her zaman başlayıp başlamadığıdır.
segmentteki ilk ifadeyle. Artık genel olarak inanılıyor ki,
Tiple girişler, bir kontrol ifadesinin esnekliğine çok az katkıda bulunur.
Artan karmaşıklığın neden olduğu okunabilirlikte azalma. Dikkat edin, birden fazla
girişler yalnızca goto'ları ve ifade etiketlerini içeren dillerde mümkündür.
Bu noktada okuyucu, kontrolden neden birden fazla çıkış yapıldığını merak edebilir.
yapılar bir tasarım sorunu olarak kabul edilmez. Bunun nedeni, tüm program-
ming dilleri, kontrol yapılarından bir tür çoklu çıkışa izin verir,
Gerekçe aşağıdaki gibidir: Bir kontrol yapısından tüm çıkışlar aşağıdakilerle sınırlıysa:
kontrolün yapıyı takip eden ilk ifadeye aktarılması,
kontrol yapısının açık bir çıkışı yoksa trol akacaktı, zararı yok
okunabilirlik ve ayrıca tehlike yok. Ancak, bir çıkışın sınırsız bir
hedeflenir ve bu nedenle kontrolün pro-
kontrol yapısını içeren gram birimi, okunabilirliğe zarar
bir programın başka herhangi bir yerindeki bir goto ifadesiyle aynı. olan diller
bir goto ifadesi, bir kontrol yapısı da dahil olmak üzere herhangi bir yerde görünmesine izin verir.
Bu nedenle, sorun, birden fazla çıkışın olup olmadığı değil, bir goto'nun dahil edilmesidir.
kontrol ifadelerine izin verilir.

Sayfa 371
350
Bölüm 8 İfade Düzeyinde Kontrol Yapıları
8.2 Seçim Açıklamaları
Bir seçim ifadesi , iki veya
bir programda daha fazla yürütme yolu. Bu tür ifadeler temeldir ve
Böhm tarafından kanıtlandığı gibi, tüm programlama dillerinin temel parçaları ve
Jakopini.
Seçim ifadeleri iki genel kategoriye ayrılır: iki yönlü ve n yönlü,
veya çoklu seçim. İki yönlü seçim ifadeleri Bölüm'de tartışılmaktadır.
8.2.1; çoklu seçim ifadeleri Bölüm 8.2.2'de ele alınmıştır.
8.2.1 İki Yönlü Seçim İfadeleri
Çağdaş emir kipinin iki yönlü seçim ifadeleri her ne kadar
ölçüler oldukça benzer, tasarımlarında bazı farklılıklar var. Genel
iki yönlü seçicinin formu aşağıdaki gibidir:
eğer kontrol_ifadesi
o zaman cümle
else cümleciği
8.2.1.1 Tasarım Konuları
İki yönlü seçiciler için tasarım konuları aşağıdaki gibi özetlenebilir:
• Seçimi denetleyen ifadenin biçimi ve türü nedir?
• Then ve else cümleleri nasıl belirtilir?
• Yuvalanmış seçicilerin anlamı nasıl belirtilmelidir?
8.2.1.2 Kontrol İfadesi
Kontrol ifadeleri, o zaman ayrılmış kelime (veya
başka bir sözdizimsel işaretleyici), sonra yan tümcesini tanıtmak için kullanılmaz. Bunun içinde
olgu daha sonra ayrılmış kelime (ya da alternatif işaretleyici) kullanıldığında, daha az olduğu
parantezlere ihtiyaç vardır, bu nedenle Ruby'de olduğu gibi genellikle atlanırlar.
Boolean veri türüne sahip olmayan C89'da aritmetik ifadeler
kontrol ifadeleri olarak kullanılmıştır. Bu ayrıca Python, C99 ve
C++. Ancak, bu dillerde ya aritmetik ya da Boolean ifadeleri
kullanılabilir. Diğer çağdaş dillerde, yalnızca Boolean ifadeleri
kontrol ifadeleri için kullanılabilir.
8.2.1.3 Madde Formu
Birçok çağdaş dilde, then ve else yan tümceleri şu şekilde görünür:
tekli ifadeler veya bileşik ifadeler. Bunun bir varyasyonu Perl'dir.
tüm o ve else yan tümceleri, birleşik ifadeler olmalıdır, öyle olsalar bile
tek ifadeler içerir. Birçok dil, bileşik oluşturmak için parantez kullanır

Sayfa 372
8.2 Seçim İfadeleri 351
then ve else yan tümcelerinin gövdesi olarak hizmet eden ifadeler. Fortran 95'te,
Ada, Python ve Ruby, then ve else yan tümceleri ifade dizileridir,
Bileşik ifadeler yerine. Tam seçim ifadesi termi-
ayrılmış bir sözcükle bu dillerde yer alır. 1
Python, bileşik ifadeleri belirtmek için girinti kullanır. Örneğin,
Eğer x> y:
x = y
"durum 1" yazdır
Eşit girintili tüm ifadeler bileşik ifadeye dahil edilir. 2
Dikkat edin , then cümleciğine girmek için o zaman yerine iki nokta üst üste kullanılır.
Python.
Cümle biçimindeki varyasyonların,
sonraki alt bölümde tartışıldığı gibi iç içe seçicilerin anlamı.
8.2.1.4 Yerleştirme Seçicileri
3. Bölümde, bir ifadenin sözdizimsel belirsizliği sorununu tartıştığımızı hatırlayın.
iki yönlü seçici ifade için basit dilbilgisi. bu belirsiz
gramer şöyleydi:
<if_stmt> eğer <logic_expr> ardından <stmt->
| eğer <logic_expr> ardından <stmt-> başka <stmt->
Sorun şuydu ki, bir seçim ifadesi bir ifadenin then yan tümcesinde yuvalandığında
seçim deyimi, bir else yan tümcesinin hangisiyle ilişkilendirilmesi gerektiği açık değildir.
yedik. Bu sorun, seçim ifadelerinin anlambilimine yansır. bağla-
aşağıdaki Java benzeri kodu ekleyin:
eğer (toplam == 0)
eğer (sayım == 0)
sonuç = 0;
Başka
sonuç = 1;
Bu ifade, olup olmamasına bağlı olarak iki farklı şekilde yorumlanabilir.
else yan tümcesi, birinci then yan tümcesi veya ikinci ile eşleştirilir. dikkat edin
girinti, else yan tümcesinin birinciye ait olduğunu gösteriyor gibi görünüyor
sonra fıkra. Ancak, Python ve F# istisnaları dışında, girinti
çağdaş dillerde anlambilim üzerinde hiçbir etkisi yoktur ve bu nedenle
onların derleyicileri.
1. Aslında Ada ve Fortran'da iki ayrılmış kelimedir, end if (Ada) veya End If (Fortran).
2. Bileşik ifadeyi takip eden ifade, if ile aynı girintiye sahip olmalıdır.

Sayfa 373
352
Bölüm 8 İfade Düzeyinde Kontrol Yapıları
Bu örnekteki sorunun özü, else yan tümcesinin iki
sonra, araya başka bir yan tümcesi olmayan yan tümceler ve sözdizimsel gösterge yok
else yan tümcesinin then yan tümcelerinden biriyle eşleşmesini belirtmek için. Java'da olduğu gibi
diğer birçok zorunlu dil, dilin statik semantiğinin belirttiği
else yan tümcesi her zaman en yakın eşleştirilmemiş ile eşleştirilir.
madde. sağlamak için sözdizimsel bir varlık yerine statik bir anlambilim kuralı kullanılır.
anlam ayrımı. Bu nedenle, örnekte, else yan tümcesi ile eşleştirilecektir.
ikinci sonra cümle. Bazı sözdizimlerinden ziyade bir kural kullanmanın dezavantajı
varlık, programcının else yan tümcesini
first then yan tümcesine alternatif ve derleyici yapı sözdizimini buldu.
olarak doğru, semantiği ise tam tersi. Alternatif anlambilimi zorlamak için
Java'da, iç if , aşağıdaki gibi bir bileşiğe konur.
if (toplam == 0) {
eğer (sayım == 0)
sonuç = 0;
}
Başka
sonuç = 1;
C, C++ ve C#, seçim ifadesiyle Java ile aynı sorunu yaşıyor
yuvalama. Perl, all o ve else yan tümcelerinin bileşik olmasını gerektirdiğinden,
değil. Perl'de önceki kod şu şekilde yazılırdı:
if (toplam == 0) {
if (sayım == 0) {
sonuç = 0;
}
} başka {
sonuç = 1;
}
Alternatif anlambilime ihtiyaç duyulsaydı,
if (toplam == 0) {
if (sayım == 0) {
sonuç = 0;
}
başka {
sonuç = 1;
}
}
İç içe seçim ifadeleri sorununu önlemenin başka bir yolu, bir
bileşik ifadeler oluşturmanın alternatif yolları. sözdizimini düşünün
Java if ifadesinin yapısı . Sonra cümlesi kontrol ifadesini takip eder.
sion ve else yan tümcesi, ayrılmış başka sözcük tarafından tanıtılır . Ne zaman

Sayfa 374
8.2 Seçim İfadeleri 353
sonra yan tümce tek bir ifadedir ve else yan tümcesi vardır, ancak orada
sonu işaretlemeye gerek yok, else ayrılmış kelime aslında sonunu işaret ediyor
sonra cümlesi. Sonra yan tümcesi bir bileşik olduğunda, bir ile sonlandırılır.
sağ dirsek. Ancak, son fıkra ise eğer o zaman ya da başka olsun, değil, bir
bileşik, tüm seçimin sonunu işaret edecek sözdizimsel bir varlık yoktur
Beyan. Bu amaç için özel bir kelimenin kullanılması şu soruyu çözer:
iç içe seçicilerin semantiği ve ayrıca durumun okunabilirliğine katkıda bulunur.
ment. Bu, Fortran 95+ Ada, Ruby'deki seçim ifadesinin tasarımıdır.
ve Lua. Örneğin, aşağıdaki Ruby ifadesini göz önünde bulundurun:
eğer a> b ardından
toplam = toplam + bir
hesap = hesap + 1
Başka
toplam = toplam + b
bcount = bcount + 1
son
Bu ifadenin tasarımı, seçim durumundan daha düzenlidir.
C-tabanlı dillerin özellikleri, çünkü biçim ne olursa olsun aynıdır.
then ve else yan tümcelerindeki ifade sayısı. (Bu aynı zamanda Perl için de geçerlidir.)
Ruby'de, then ve else cümleciklerinin deyim dizilerinden oluştuğunu hatırlayın.
Bileşik ifadeler yerine. Seçicinin ilk yorumu
else yan tümcesinin eşleştiği bu bölümün başındaki örnek
iç içe if , Ruby'de aşağıdaki gibi yazılabilir:
Eğer toplam == 0 sonra
eğer sayımı == 0 ardından
sonuç = 0
Başka
sonuç = 1
son
son
Çünkü son saklıdır kelime iç içe kapanır eğer o açıktır, başka olduğunu
yan tümcesi iç then yan tümcesi ile eşleştirilir.
Seçim ifadesinin başındaki ikinci yorum
else yan tümcesinin dış if ile eşleştirildiği bu bölüm yazılabilir.
Ruby'de şu şekilde:
Eğer toplam == 0 sonra
eğer sayımı == 0 ardından
sonuç = 0
son
Başka
sonuç = 1
son

Sayfa 375
354
Bölüm 8 İfade Düzeyinde Kontrol Yapıları
Python ile yazılmış aşağıdaki ifade anlamsal olarak şuna eşdeğerdir:
yukarıdaki son Ruby ifadesi:
Eğer toplam == 0:
eğer sayı == 0 :
sonuç = 0
başka :
sonuç = 1
else: satırı iç içe if ile aynı sütunda başlayacak şekilde girintiliyse ,
else yan tümcesi iç if ile eşleştirilir .
ML'nin iç içe seçicilerle bir sorunu yoktur çünkü
else-less if ifadelerine izin verin .
8.2.1.5 Seçici İfadeler
ML, F# ve LISP işlevsel dillerinde seçici bir ifade değildir; bu
bir değerle sonuçlanan bir ifade. Bu nedenle, başka herhangi bir yerde görünebilir
ifadesi görünebilir. F# ile yazılmış aşağıdaki örnek seçiciyi düşünün:
izin y =
eğer x> 0 ardından x
yoksa 2 * x;;
Bu, y adını oluşturur ve olup olmamasına bağlı olarak x veya 2 * x olarak ayarlar.
x sıfırdan büyüktür.
Bir F # eğer onun hükmü veya cümleleri oluşturursanız ihtiyaç örneğin bir değer döndürmez
yan etkiler, belki de çıktı ifadeleriyle. Ancak, eğer if ifadesi
bir değer döndürün, yukarıdaki örnekte olduğu gibi, bir else cümleciğine sahip olmalıdır.
8.2.2 Çoklu Seçim İfadeleri
Çoklu seçim ifadesi herhangi bir sayı birinin seçilmesine olanak
ifadeler veya ifade grupları. Bu nedenle, bir seçicinin genellemesidir.
Aslında, iki yönlü seçiciler, çoklu seçiciyle oluşturulabilir.
Bir programda ikiden fazla kontrol yolu arasından seçim yapma ihtiyacı
yaygındır. İki yönlü seçicilerden çoklu seçici oluşturulabilmesine rağmen
ve gotos, ortaya çıkan yapılar hantal, güvenilmez ve zor
yaz ve oku. Bu nedenle, özel bir yapıya ihtiyaç olduğu açıktır.
8.2.2.1 Tasarım Konuları
Birden çok seçici için tasarım sorunlarından bazıları, bunlardan bazılarına benzer.
iki yönlü seçiciler için. Örneğin, bir sorun türü sorusudur.
seçicinin dayandığı ifade. Bu durumda, olasılık aralığı
kısmen olası seçimlerin sayısı daha fazla olduğu için daha büyüktür. iki yönlü

Sayfa 376
8.2 Seçim İfadeleri 355
seçicinin yalnızca iki olası değere sahip bir ifadeye ihtiyacı var. Diğer bir konu
tekli ifadelerin, bileşik ifadelerin veya ifade dizilerinin
seçilebilir. Daha sonra, yalnızca tek bir seçilebilir segmentin olup olmadığı sorusu vardır.
deyim yürütüldüğünde yürütülebilir. Bu sorun için değil
iki yönlü seçiciler, çünkü her zaman yan tümcelerden yalnızca birinin bir
bir yürütme sırasında kontrol yolu. Göreceğimiz gibi, bu sorunun çözümü
çoklu seçiciler için güvenilirlik ve esneklik arasında bir ödünleşim söz konusudur. Bir diğeri
sorun, vaka değeri belirtimlerinin biçimidir. Son olarak şu konu var
yapan bir değere değerlendiren seçici ifadeden ne sonuçlanmalıdır?
bölümlerden birini seçmeyin. (Böyle bir değer,
seçilebilir segmentler.) Buradaki seçim, duruma izin vermemek arasındadır.
ortaya çıkma ve ifadeye sahip olma, ortaya çıktığında hiçbir şey yapmaz.
Aşağıda bu tasarım sorunlarının bir özeti yer almaktadır:
• Seçimi denetleyen ifadenin biçimi ve türü nedir?
• Seçilebilir segmentler nasıl belirlenir?
• Yapıdaki yürütme akışı, yalnızca tek bir
seçilebilir segment?
• Vaka değerleri nasıl belirlenir?
• Varsa, temsil edilmeyen seçici ifade değerleri nasıl ele alınmalıdır?
8.2.2.2 Çoklu Seçici Örnekleri
Aynı zamanda C++, Java'nın bir parçası olan C çoklu seçici ifadesi, switch ,
ve JavaScript, nispeten ilkel bir tasarımdır. Onun genel şekli
geçiş ( ifade ) {
durum sabiti _ ifade 1 : ifade 1 ;
. . .
durum sabiti n : deyim_n ;
[ varsayılan : ifade n+1 ]
}
burada kontrol ifadesi ve sabit ifadeler bazı ayrıktır
tip. Bu, tamsayı türlerini, ayrıca karakterleri ve numaralandırma türlerini içerir.
Seçilebilir ifadeler, ifade dizileri, bileşik ifadeler,
veya bloklar. İsteğe bağlı varsayılan segment, temsil edilmeyen değerleri içindir.
kontrol ifadesi. Kontrol ifadesinin değeri temsil edilmezse ve
varsayılan segment yok, o zaman ifade hiçbir şey yapmaz.
Anahtar deyimi sonunda örtülü dalları sağlamaz onun
kod bölümleri. Bu, kontrolün birden fazla seçilebilir
tek bir yürütmede kod segmenti. Aşağıdaki örneği göz önünde bulundurun:
geçiş (dizin) {
durum 1:

Sayfa 377
356
Bölüm 8 İfade Düzeyinde Kontrol Yapıları
durum 3: tek += 1;
toplam += dizin;
durum 2:
durum 4: hatta += 1;
sumeven += dizin;
varsayılan : printf("Anahtarda hata, dizin = %d\n", dizin);
}
Bu kod, her yürütmede hata mesajını yazdırır. Aynı şekilde, kod
2 ve 4 sabitler her zaman kodunu çalıştırılır 1 ya da 3 sabitler
Idam edildi. Bu segmentleri mantıksal olarak ayırmak için açık bir dal olmalıdır.
dahil. Mola aslında kısıtlı git olduğu açıklamada, normalde
switch ifadelerinden çıkmak için kullanılır .
Aşağıdaki switch deyimi, her yürütmeyi şu şekilde kısıtlamak için break kullanır:
tek bir seçilebilir segment:
geçiş (dizin) {
durum 1:
durum 3: tek += 1;
toplam += dizin;
ara ;
durum 2:
durum 4: hatta += 1;
sumeven += dizin;
ara ;
varsayılan : printf("Anahtarda hata, dizin = %d\n", dizin);
}
Bazen, kontrolün seçilebilir bir noktadan akmasına izin vermek uygundur.
başka bir kod segmenti. Örneğin, yukarıdaki örnekte, segmentler
1 ve 2 durum değerleri boştur, bu da kontrolün bölümlere akmasına izin verir.
sırasıyla 3 ve 4 . Bu, örtük dalların olmamasının nedenidir.
anahtar deyim. Bu tasarımdaki güvenilirlik sorunu,
Bir segmentte bir break ifadesinin yanlışlıkla yokluğu, kontrolün
sonraki bölüm yanlış. C'nin anahtarının tasarımcıları bir düşüş ticareti yaptı
esneklikte bir artış için güvenilirlikte. Ancak araştırmalar göstermiştir ki,
seçilebilir bir segmentten diğerine kontrol akışına sahip olma yeteneği nadiren
Kullanılmış. C'nin anahtarı , ALGOL'deki çoklu seçim ifadesinde modellenmiştir.
Seçilebilir segmentlerden örtük dalları da olmayan 68.
C switch deyiminin yerleştirilmesi konusunda neredeyse hiçbir kısıtlaması yoktur.
normal ifade etiketleriymiş gibi işlem gören vaka ifadeleri.
Bu gevşeklik, anahtar gövdesi içinde oldukça karmaşık bir yapıya neden olabilir. bu
aşağıdaki örnek Harbison ve Steele'den (2002) alınmıştır.
anahtar (x)
varsayılan :
if (asal(x))

Sayfa 378
8.2 Seçim İfadeleri 357
durum 2: durum 3: durum 5: durum 7:
process_prime(x);
Başka
durum 4: durum 6: durum 8: durum 9: durum 10:
process_composite(x);
Bu kod şeytani bir şekilde karmaşık bir şekle sahip gibi görünebilir, ancak tasarlanmıştır.
gerçek bir sorun için ve bu sorunu çözmek için doğru ve verimli bir şekilde çalışır. 3
Java anahtarı, büyük/küçük harf kullanımına izin vermeyerek bu tür karmaşıklığı önler
ifadelerin gövdesinin üst seviyesi dışında herhangi bir yerde görünmesini
değiştirmek.
C# switch ifadesi, C tabanlı öncüllerinden farklıdır
iki şekilde. İlk olarak, C#, örtük olana izin vermeyen statik bir anlambilim kuralına sahiptir.
birden fazla segmentin yürütülmesi. Kural şu ​​ki, her seçilebilir segment
açık bir koşulsuz dal ifadesi ile bitmelidir: ya bir break ,
kontrolü switch ifadesinin dışına aktaran veya bir goto,
kontrolü seçilebilir segmentlerden birine (veya hemen hemen başka herhangi bir yere) aktarın.
Örneğin,
geçiş (değer) {
durum -1:
Negatifler++;
ara ;
durum 0:
Sıfırlar++;
durum 1'e git ;
durum 1:
pozitifler++;
varsayılan :
Console.WriteLine("Anahtarda hata\n");
}
Console.WriteLine'ın , C#'ta dizeleri görüntüleme yöntemi olduğunu unutmayın .
C# anahtarının öncekilerden farklı olmasının diğer bir yolu ,
kontrol ifadesi ve vaka ifadeleri C#'da dizeler olabilir.
PHP'nin anahtarı , C'nin anahtarının sözdizimini kullanır, ancak daha fazla tür esnekliğine izin verir.
yetenek. Vaka değerleri PHP skaler türlerinden herhangi biri olabilir: string, integer veya
çift ​​hassasiyet. C'de olduğu gibi, seçilenin sonunda ara yoksa
segment, yürütme sonraki segmentte devam eder.
Ruby, her ikisi de olan iki çoklu seçim yapısına sahiptir.
vaka ifadeleri olarak adlandırılır ve her ikisi de son ifadenin değerini verir
3. Sorun, x asal ve process_composite olduğunda process_prime'ı çağırmaktır.
x asal olmadığında. Anahtar gövdesinin tasarımı, optimize etme girişiminden kaynaklanmıştır.
x'in en sık 1 ila 10 aralığında olduğu bilgisine dayanarak.

Sayfa 379
358
Bölüm 8 İfade Düzeyinde Kontrol Yapıları
değerlendirildi. Ruby'nin vaka ifadelerinin burada açıklanan tek versiyonu,
anlamsal olarak iç içe if ifadeleri listesine benzer:
dava
ne zaman Boolean_expression sonra ifade
. . .
ne zaman Boolean_expression sonra ifade
[ başka ifade ]
son
Bu durum ifadesinin anlamı, Boolean ifadelerinin
yukarıdan aşağıya birer birer değerlendirilir. Case ifadesinin değeri,
Boolean ifadesi doğru olan ilk sonra ifadenin değeri. diğer
bu ifadede true ifadesini temsil eder ve else yan tümcesi isteğe bağlıdır. İçin
örnek, 4
sıçrama = durum
yıl % 400 == 0 olduğunda doğru
yıl % 100 == 0 olduğunda yanlış
başka yıl % 4 == 0
son
Bu durum ifadesi, yıl artık yıl ise doğru olarak değerlendirilir .
Diğer Ruby durum ifadesi formu, Java anahtarına benzer. Perl,
Python ve Lua, çoklu seçim ifadelerine sahip değildir.
8.2.2.3 Çoklu Seçim Yapılarının Uygulanması
Bir çoklu seçim ifadesi, esasen,
kodu, burada n, seçilebilir segmentlerin sayısıdır. Böyle bir devleti uygulamak-
ment çoklu koşullu dal talimatları ile yapılmalıdır. Düşünmek
yine C switch ifadesinin genel biçimi, aralarla birlikte:
geçiş ( ifade ) {
durum sabit_ifadesi 1 : ifade 1 ;
ara ;
. . .
durum sabiti n : deyim n ;
ara ;
[ varsayılan : ifade n+1
]
}
4. Bu örnek Thomas ve ark. (2005).

Sayfa 380
8.2 Seçim İfadeleri 359
Bu ifadenin basit bir çevirisi şöyledir:
İfadeyi t olarak değerlendirmek için kod
dallara git
etiket 1 : deyim 1 için kod
goto, dışarı
. . .
etiket n : n ifadesi için kod
goto, dışarı
varsayılan: n+1 ifadesi için kod
goto, dışarı
dallar: eğer t = sabit_ifade 1 etiket 1'e git
. . .
eğer t = sabit_ifade n, etiket n'ye git
varsayılana git
dışarı:
Seçilebilir segmentler için kod, dallardan önce gelir, böylece hedefler
dalların tümü, dallar oluşturulduğunda bilinir. Bir alternatif
bu kodlanmış koşullu dallara, vaka değerlerini ve etiketleri bir tabloya koymaktır.
ve doğru etiketi bulmak için döngülü doğrusal bir arama kullanın. Bu daha az gerektirir
kodlanmış koşullardan daha boşluk.
Bir durum tablosunda koşullu dalların veya doğrusal bir aramanın kullanılması ve
etiket sayısı kabul edilebilir basit ama verimsiz bir yaklaşımdır.
vakalar küçük, diyelim 10'dan az. Ortalama olarak yaklaşık yarısı kadar test gerektirir.
doğru olanı bulmak için durumlar vardır. Seçilecek varsayılan durum için, diğer tüm
durumlarda test edilmelidir. 10 veya daha fazla durum içeren ifadelerde düşük verim
bu form basitliği ile haklı değildir.
Vaka sayısı 10 veya daha fazla olduğunda, derleyici bir karma oluşturabilir
yaklaşık olarak eşit (ve
seçilebilir segmentlerden herhangi birini seçmek için kısa) süreler. Dil izin verirse
Ada ve Ruby'de olduğu gibi vaka ifadeleri için değer aralıkları, hash yöntemi
uygun değil. Bu durumlar için, durum değerleri ve segmentlerden oluşan ikili bir arama tablosu
ment adresleri daha iyidir.
Vaka değerlerinin aralığı nispeten küçükse ve yarısından fazlaysa
tüm değerler aralığı temsil edilir, indeksleri büyük/küçük harf değerleri olan bir dizi
ve değerleri olan segment etiketleri oluşturulabilir. dizi öğeleri olan
indeksler temsil edilen vakalar arasında değil değerler varsayılan ile doldurulur
segmentin etiketi. Ardından doğru segment etiketini bulmak dizi indeksi ile bulunur.
ing, ki bu çok hızlı.
Tabii ki, bu yaklaşımlar arasında seçim yapmak ek bir yüktür.
derleyici. Pek çok derleyicide yalnızca iki farklı yöntem mevcuttur.
Diğer durumlarda olduğu gibi, en verimli yöntem maliyetlerinin belirlenmesi ve kullanılması
daha fazla derleyici zamanı.

Sayfa 381
360
Bölüm 8 İfade Düzeyinde Kontrol Yapıları
8.2.2.4 Eğer Kullanarak Çoklu Seçim
Birçok durumda, bir switch veya case ifadesi birden fazla durum için yetersizdir.
Seçim (Ruby'nin durum bir istisnadır). Örneğin, seçimlerin yapılması gerektiğinde
bazı sıralı türden ziyade bir Boole ifadesi temelinde yapılmış, iç içe geçmiş
çoklu seçiciyi simüle etmek için iki yönlü seçiciler kullanılabilir. hafifletmek için
derin iç içe iki yönlü seçicilerin zayıf okunabilirliği, örneğin bazı diller
Perl ve Python, özellikle bu kullanım için genişletildi. uzantı
bazı özel kelimelerin dışarıda bırakılmasına izin verir. Özellikle, else-if dizileri
tek bir özel sözcükle değiştirilir ve iç içe geçmiş sözcükteki kapanış özel sözcüğü
eğer düşürülür. İç içe seçici, daha sonra bir else-if yan tümcesi olarak adlandırılır . Yi hesaba kat
aşağıdaki Python seçici ifadesi (Python'da else- if'in elif olarak yazıldığını unutmayın ):
eğer Kontun <10:
bag1 = Doğru
elif sayısı < 100 :
bag2 = Doğru
elif sayısı < 1000 :
bag3 = Doğru
aşağıdakine eşdeğerdir:
eğer Kontun <10:
bag1 = Doğru
Başka :
eğer Kontun <100:
bag2 = Doğru
Başka :
eğer 1000 <sayımı:
bag3 = Doğru
başka :
bag4 = Doğru
Else-if sürümü (ilk), ikisinin daha okunaklı olanıdır. Dikkat edin, bu
örnek, bir switch ifadesi ile kolayca simüle edilmez , çünkü her biri seçilebilir
ifade bir Boole ifadesi temelinde seçilir. Bu nedenle, else-if
ifadesi yedekli bir switch biçimi değildir . Aslında, çoklu seçicilerin hiçbiri
çağdaş dillerde if-then-else-if ifadesi kadar geneldir. Bir opera-
else-if tümceleri ile genel bir seçici deyimin tional semantik açıklaması,
E'lerin mantıksal ifadeler ve S'lerin ifadeler olduğu burada verilmiştir:
Eğer E 1 , goto 1
Eğer E 2 , goto 2
. . .
1: S 1
goto, dışarı
2: s 2

Sayfa 382
8.2 Seçim İfadeleri 361
goto, dışarı
. . .
dışarı: . . .
Bu açıklamadan, çoklu seçim arasındaki farkı görebiliriz.
yapılar ve else-if ifadeleri: Bir çoklu seçim ifadesinde, tüm E'ler
tek bir ifadenin değeri arasındaki karşılaştırmalarla sınırlı olacaktır
ve diğer bazı değerler.
else-if ifadesini içermeyen diller aynı bağlamı kullanabilir.
trol yapısı, sadece biraz daha fazla yazarak.
Yukarıdaki Python örneği if-then-else-if ifadesi şu şekilde yazılabilir:
Ruby vaka ifadesi:
dava
ne zaman sayısı <10 o yastığı 1 = true
zaman sayımı <100 sonra bag2 = true
zaman sayımı <1000 sonra bag3 = true
son
Else-if ifadeleri ortak matematik ifadesine dayanmaktadır,
koşullu ifade.
Matematiksel koşullara dayanan Şema çoklu seçicisi
tional ifadeler, COND adlı özel bir form işlevidir . COND biraz
matematiksel koşullu ifadenin genelleştirilmiş versiyonu; daha fazlasını sağlar
birden fazla yüklemin aynı anda doğru olması. Çünkü farklı matematiksel
koşullu ifadeler parametrelerin farklı rakamlar var COND değil
sabit sayıda gerçek parametre gerektirir. COND için her parametre bir çifttir
ilkinin yüklem olduğu ifadeler ( #T veya #F olarak değerlendirilir ).
COND'un genel formu şu şekildedir:
(KOND
( yüklem 1 ifade 1 )
( yüklem 2 ifade 2 )
. . .
( yüklem n ifade n )
[(ELSE ifadesi n+1 )]
)
burada BAŞKA maddesi isteğe bağlıdır.
COND'un semantiği aşağıdaki gibidir: Parametrelerin yüklemleri
ilkinden biri #T olarak değerlendirene kadar sırayla değerlendirilir . bu
#T olduğu bulunan ilk yüklemi takip eden ifade daha sonra değerlendirilir.
ated ve değeri COND değeri olarak döndürülür . Eğer yüklemlerin hiçbiri değilse
true ve bir ELSE var , ifadesi değerlendirilir ve değer döndürülür.
Yüklem hiçbiri doğru ve hiçbir yoksa BAŞKA , değeri COND olduğunu
belirtilmemiş. Bu nedenle, tüm COND ' ler bir ELSE içermelidir .

Sayfa 383
362
Bölüm 8 İfade Düzeyinde Kontrol Yapıları
COND için aşağıdaki örnek çağrıyı göz önünde bulundurun :
(KOND
((> xy) "x, y'den büyüktür")
((< xy) "y, x'ten büyüktür")
(ELSE "x ve y eşittir")
)
Dize değişmezlerinin kendilerini değerlendirdiğine dikkat edin, böylece bu COND çağrısı yapıldığında
değerlendirilir, bir dize sonucu üretir.
F# , seçici olarak kalıp eşleştirmeyi kullanan bir eşleşme ifadesi içerir
çoklu seçim yapısı sağlamak için.
8.3 Yinelemeli İfadeler
Bir tekrarlanan açıklamada devlet bir açıklama veya koleksiyon neden olandır
sıfır, bir veya daha fazla kez yürütülecek. Yinelemeli bir ifade genellikle
döngü denir . Plankalkül'den gelen her programlama dili şunları içerir:
kod bölümlerinin yürütülmesini tekrarlamak için bir yöntem. yineleme
bilgisayarın gücünün özü. Eğer tekrarlayan yürütmenin bazı araçları
bir ifadenin veya ifadelerin toplanması mümkün değildi, programcılar
her eylemi sırayla belirtmesi gerekecektir; faydalı programlar olur
çok büyük ve esnek değil ve yazmak kabul edilemez derecede uzun zaman alıyor ve
depolanacak devasa miktarda bellek.
Programlama dillerindeki ilk yinelemeli ifadeler doğrudan
dizilerle ilgili. Bunun nedeni, ticaretin ilk yıllarında
bilgisayarcılara göre, hesaplama doğası gereği büyük ölçüde sayısaldı ve sık sık döngüler kullanıyordu.
dizilerdeki verileri işler.
Birkaç yineleme kontrol ifadesi kategorisi geliştirilmiştir.
Birincil kategoriler, tasarımcıların iki temel soruyu nasıl yanıtladıklarıyla tanımlanır.
tasarım soruları:
• Yineleme nasıl kontrol edilir?
• Kontrol mekanizması döngü ifadesinde nerede görünmelidir?
Yineleme kontrolü için birincil olasılıklar mantıksal, sayma veya
ikisinin birleşimi. Kontrolün yeri için ana seçenekler
mekanizma, döngünün üstü veya altıdır. Üst ve alt
burada fiziksel değil, mantıksal ifadeler vardır. mesele fizik değil
kontrol mekanizmasının yerleştirilmesi; daha ziyade, mekanizmanın olup olmadığıdır.
yürütülür ve deyim gövdesinin yürütülmesinden önce veya sonra denetimi etkiler.
Kullanıcının kontrolü nereye koyacağına karar vermesine izin veren üçüncü bir seçenek,
Bölüm 8.3.3'te tartışılmıştır.
Vücut iteratif ifadesinin tabloların koleksiyon
yürütme yineleme ifadesi tarafından kontrol edilir. Biz terimini kullanmak ön test etmek
döngü gövdesi yürütülmeden önce döngü tamamlama testinin gerçekleştiği anlamına gelir

Sayfa 384
8.3 Yinelemeli İfadeler 363
ve son test , döngü gövdesi yürütüldükten sonra gerçekleştiği anlamına gelir. yineleme
ifadesi ve ilişkili döngü gövdesi birlikte bir yineleme ifadesi oluşturur .
Birincil yineleme ifadelerine ek olarak, bir alternatifi tartışıyoruz.
kendi başına bir sınıfta olan form: kullanıcı tanımlı yineleme kontrolü.
8.3.1 Karşı Kontrollü Döngüler
Bir sayma yinelemeli kontrol ifadesinin döngü değişkeni adı verilen bir değişkeni vardır.
mümkün , burada sayım değeri korunur. Ayrıca bazı araçları içerir
belirten başlangıç ve son çevrim değişken değerlerini ve farklı olarak da
genellikle adım boyutu olarak adlandırılan sıralı döngü değişken değerleri arasındaki fark .
Bir ilmek, ilk terminali ve stepSize özellikler olarak adlandırılır ilmek
parametreler .
Mantıksal olarak kontrol edilen döngüler, karşıt döngülerden daha genel olsa da,
kontrollü döngüler, mutlaka daha yaygın olarak kullanılmazlar. Çünkü
karşı kontrollü döngüler daha karmaşıktır, tasarımları daha zorludur.
Sayaç kontrollü döngüler bazen makine talimatlarıyla desteklenir.
bu amaç için tasarlanmış tarifler. Ne yazık ki, makine mimarisi
mimarlığın zamanında programlamaya yönelik geçerli yaklaşımlardan daha uzun yaşamak
tur tasarımı. Örneğin, VAX bilgisayarların çok uygun bir talimatı vardır.
Fortran'ın son test karşı kontrollü döngülerinin uygulanması için
VAX'ın tasarımı sırasında (1970'lerin ortaları) vardı. Ama Fortran artık
VAX bilgisayarları yaygın olarak kullanılmaya başladığında böyle bir döngü vardı (
bir ön test döngüsü ile değiştirilir).
8.3.1.1 Tasarım Sorunları
Yinelemeli karşı kontrollü ifadeler için birçok tasarım sorunu vardır. bu
döngü değişkeninin doğası ve döngü parametreleri bir dizi tasarım sağlar
konular. Döngü değişkeninin türü ve açıkça döngü parametrelerinin türü
aynı veya en azından uyumlu olmalı, ancak hangi türlere izin verilmelidir?
Görünen bir seçenek tam sayıdır, peki ya numaralandırma, karakter ve
kayan nokta türleri? Başka bir soru, döngü değişkeninin normal olup olmadığıdır.
mal değişkeni, kapsam açısından veya bazı özel kapsamı olması gerekip gerekmediği.
Kullanıcının döngü değişkenini veya içindeki döngü parametrelerini değiştirmesine izin vermek
döngü, anlaşılması çok zor olan bir koda yol açabilir, bu nedenle başka bir soru-
Bu tür izin verilmesiyle elde edilebilecek ek esnekliğin olup olmadığıdır.
değişiklikler bu ek karmaşıklığa değer. hakkında benzer bir soru ortaya çıkıyor.
döngü parametrelerinin değerlendirildiği zaman sayısı ve belirli süre
ated: Sadece bir kez değerlendirilirlerse, basit ama daha az esnek döngülerle sonuçlanır.
Aşağıda bu tasarım sorunlarının bir özeti yer almaktadır:
• Döngü değişkeninin türü ve kapsamı nelerdir?
• Döngü değişkeni veya döngü parametrelerinin değiştirilmesi yasal olmalı mı?
ve eğer öyleyse, değişiklik döngü kontrolünü etkiler mi?
• Döngü parametreleri yalnızca bir kez mi yoksa her yineleme için bir kez mi değerlendirilmeli?

Sayfa 385
364
Bölüm 8 İfade Düzeyinde Kontrol Yapıları
8.3.1.2 Açıklama için Ada
Ada for ifadesi aşağıdaki forma sahiptir:
[ters] ayrık_aralık döngüsündeki değişken için
. . .
son döngü ;
Ayrık aralık, 1..10 gibi bir tamsayı veya numaralandırma türünün bir alt aralığıdır.
veya Pazartesi.. Cuma . Ters ayrılmış kelime, mevcut olduğu zaman, belirtir
ayrık aralığın değerleri döngü değişkenine ters sırada atanır.
Ada for ifadesinin en ilginç yeni özelliği kapsamdır .
döngü aralığı olan döngü değişkeninin. Değişken dolaylı olarak
En ilan için deyimi ve dolaylı döngü sona ermesinden sonra bildirilmeyen.
örneğin,
Sayı : Kayan := 1.35;
için Kont içinde 1..10 döngü
Toplam := Toplam + Say;
son döngü ;
Şamandıra değişken Sayısı etkilenmez için döngü. Döngü sonlandırıldığında
tion, Count değişkeni hala 1.35 değeriyle Float tipindedir . Ayrıca
Float -type Count değişkeni , döngünün gövdesindeki koddan gizlenir,
örtük olarak beyan edilen Count döngü sayacı tarafından maskeleniyor
ayrık aralığın türü, Tamsayı .
Ada döngü değişkenine döngü gövdesinde bir değer atanamaz. değişken
ayrık aralığı belirtmek için kullanılan yetenekler döngüde değiştirilebilir, ancak
aralık yalnızca bir kez değerlendirilir, bu değişiklikler döngü kontrolünü etkilemez. o
Ada içine dalına yasal değildir için döngü gövdesinin. Aşağıdaki operasyonel
Ada for döngüsünün anlamsal açıklaması :
[for_var tanımlayın ( türünün türü ayrık aralığınkidir ) ]
[ayrık aralığı değerlendirin]
döngü:
Eğer [ayrık aralığında kalan bir element vardır] , goto üzerinden
for_var = [ayrık aralığın sonraki öğesi]
[döngü gövdesi]
döngüye git
dışarı:
[için_var tanımını kaldır]
Döngü değişkeninin kapsamı döngü gövdesi olduğundan, döngü değişkenleri
döngü sonlandırıldıktan sonra tanımlanmaz, bu nedenle değerleri alakalı değildir.
8.3.1.3 C-Tabanlı Diller için Açıklama
C'nin for ifadesinin genel formu şu şekildedir:

Sayfa 386
8.3 Yinelemeli İfadeler 365
for ( ifade_1 ; ifade_2 ; ifade_3 )
döngü gövdesi
Döngü gövdesi tek bir deyim, bir bileşik deyim veya bir null olabilir.
Beyan.
Çünkü C'deki atama ifadeleri sonuçlar üretir ve bu nedenle
taraflı ifadeler, for ifadesindeki ifadeler genellikle atamadır
ifadeler. İlk ifade başlatma içindir ve yalnızca bir kez değerlendirilir,
zaman için deyim yürütme başlar. İkinci ifade döngüdür
kontrol ve döngü gövdesinin her yürütülmesinden önce değerlendirilir. her zamanki gibi
C, sıfır değeri yanlış anlamına gelir ve sıfır olmayan tüm değerler doğru anlamına gelir. Bu nedenle, eğer
ikinci ifadenin değeri sıfırdır, for sonlandırılır; aksi halde,
döngü gövdesi deyimleri yürütülür. C99'da ifade ayrıca bir Bool- olabilir.
ean türü. Bir C99 Boole türü yalnızca 0 veya 1 değerlerini saklar.
içinde For loop gövdesinin her uygulamadan sonra yürütülür. Sıklıkla kullanılır
döngü sayacını artırmak için. C'nin operasyonel semantik açıklaması
for deyimi sonraki gösterilir. C ifadeleri ifade olarak kullanılabildiğinden,
ifade değerlendirmeleri ifadeler olarak gösterilir.
ifade_1
döngü:
Eğer expression_2 = 0 git üzerinden
[döngü gövdesi]
ifade_3
döngüye git
dışarı: . . .
Aşağıda bir iskelet C for deyimi örneği verilmiştir :
for (sayım = 1; say <= 10; say++)
. . .
}
C'ler arasında ifadelerin tamamı için isteğe bağlıdır. Eksik bir ikinci ifade
sion doğru kabul edilir, bu nedenle bir olmadan bir for , potansiyel olarak sonsuz bir döngüdür.
Birinci ve/veya üçüncü ifadeler yoksa, herhangi bir varsayım yapılmaz. İçin
örneğin, ilk ifade yoksa, bu yalnızca başlatmanın olmadığı anlamına gelir.
yer alır.
C olduğunu Not için sayılmaz ihtiyacı. Kolayca sayma ve mantıksal modelleme yapabilir.
sonraki bölümde gösterildiği gibi döngü yapıları.
Tasarım seçenekleri için C aşağıdaki gibidir: Açık bir döngü yoktur
değişkenler veya döngü parametreleri. İlgili tüm değişkenler döngüde değiştirilebilir
gövde. İfadeler daha önce belirtilen sıraya göre değerlendirilir. Ona rağmen
tahribat yaratabilir, döngü gövdesi için bir C'ye dallanmak yasaldır .
C's for , Ada'nın sayma döngüsü ifadesinden daha esnektir, çünkü
ifadelerin her biri birden fazla ifade içerebilir ve bu da
herhangi bir türden olabilen çoklu döngü değişkenleri. Birden fazla ifade olduğunda

Sayfa 387
366
Bölüm 8 İfade Düzeyinde Kontrol Yapıları
for ifadesinin tek bir ifadesinde kullanıldığında, virgülle ayrılırlar.
Tüm C ifadelerinin değerleri vardır ve bu çoklu ifade biçimi istisna değildir.
tion. Böyle bir çoklu ifadenin değeri, son bileşenin değeridir.
Aşağıdakileri göz önünde bulundurun için açıklamada:
için (sayım1 = 0, sayı2 = 1.0;
sayı1 <= 10 && sayı2 <= 100.0;
toplam = ++say1 + sayı2, sayı2 *= 2.5);
Bunun operasyonel semantik açıklaması
say1 = 0
sayı2 = 1.0
döngü:
eğer say1 > 10 Goto dışarı
eğer say2 > 100.0 git dışarı
say1 = say1 + 1
toplam = say1 + say2
say2 = say2 * 2,5
döngüye git
dışarı: …
C for deyimi için örnek gerekli değildir ve bu nedenle bir döngüye sahip değildir.
gövde. İstenen tüm eylemler, for ifadesinin kendisinin değil, kendisinin bir parçasıdır.
onun vücudunda. Birinci ve üçüncü ifadeler çoklu ifadelerdir. her ikisinde de
bu durumlarda, ifadenin tamamı değerlendirilir, ancak elde edilen değer değerlendirilmez.
döngü kontrolünde kullanılır.
C99 ve C++' ın for ifadesi önceki sürümlerden farklıdır
C'nin iki yolu. İlk olarak, bir aritmetik ifadeye ek olarak, bir
Döngü kontrolü için Boole ifadesi. İkincisi, ilk ifade şunları içerebilir:
değişken tanımları. Örneğin,
for ( int sayı = 0; sayım < len; sayım++) { . . . }
for deyiminde tanımlanan bir değişkenin kapsamı , tanımından
döngü gövdesinin sonu.
Java ve C#' ın for deyimi, döngü dışında C++'ınki gibidir.
kontrol ifadesi boolean ile sınırlıdır .
Tüm C tabanlı dillerde, son iki döngü parametresi değerlendirilir
her yineleme ile. Ayrıca, döngü parametresinde görünen değişkenler
ifade döngü gövdesinde değiştirilebilir. Bu nedenle, bu döngüler uzak olabilir
Ada'nın sayma döngüsünden daha karmaşıktır ve genellikle daha az güvenilirdir.
8.3.1.4 Python için Açıklama
Python genel form için DİR

Sayfa 388
8.3 Yinelemeli İfadeler 367
için loop_variable olarak nesne:
- döngü gövdesi
[ başka :
- else cümleciği]
Döngü değişkenine, genellikle bir aralık olan nesnedeki değer atanır.
döngü gövdesinin her yürütmesi için. else yan tümcesi, mevcut olduğunda yürütülür
döngü normal bir şekilde sona ererse.
Aşağıdaki örneği göz önünde bulundurun:
için sayım içinde [2, 4, 6]:
baskı sayısı
üretir
2
4
6
Python'daki çoğu basit sayma döngüsü için aralık işlevi kullanılır.
aralık bir, iki veya üç parametre alır. Aşağıdaki örnekler şeytan-
aralığın eylemlerini sıralayın :
aralık (5) [0, 1, 2, 3, 4] döndürür
aralık (2, 7) [2, 3, 4, 5, 6] döndürür
aralık (0, 8, 2) [0, 2, 4, 6] döndürür
Aralığın hiçbir zaman belirli bir parametre aralığındaki en yüksek değeri döndürmediğini unutmayın .
8.3.1.5 İşlevsel Dillerde Karşı Kontrollü Döngüler
Zorunlu dillerdeki sayaç kontrollü döngüler bir sayaç değişkeni kullanır, ancak
bu tür değişkenler saf işlevsel dillerde mevcut değildir. yinelemeden ziyade
Tekrarlamayı kontrol etmek için işlevsel diller özyinelemeyi kullanır. Ziyade
bir ifadede, işlevsel diller özyinelemeli bir işlev kullanır. Sayma döngüleri
fonksiyonel dillerde şu şekilde simüle edilebilir: Sayaç bir
döngü gövdesini tekrar tekrar yürüten bir işlev için parametre,
döngü işlevine parametre olarak gönderilen ikinci bir işlevde belirtilebilir. Böyle,
böyle bir döngü işlevi, vücut işlevini ve tekrar sayısını alır
parametreler olarak.
adlı sayma döngülerini simüle etmek için bir F# fonksiyonunun genel biçimi
forLoop bu durumda aşağıdaki gibidir:
Rec izin forloop loopBody temsilcileri =
Eğer temsilcileri <= 0 , sonra
()

Sayfa 389
368
Bölüm 8 İfade Düzeyinde Kontrol Yapıları
Başka
döngüBody()
forLoop loopBody, (tekrarlar - 1);;
Bu fonksiyonda, loopBody parametresi, nesnenin gövdesine sahip fonksiyondur.
döngü ve tekrar parametresi tekrar sayısıdır. Ayrılmış kelime
rec özyinelemeli olduğunu belirtmek için işlevin adından önce görünür. bu
boş parantezler hiçbir şey yapmaz; oradalar çünkü F#'da boş bir ifade
yasa dışıdır ve her if ifadesinin bir else maddesine sahip olması gerekir.
8.3.2 Mantıksal Kontrollü Döngüler
Çoğu durumda, ifade koleksiyonları tekrar tekrar yürütülmelidir, ancak
tekrarlama kontrolü, bir sayaçtan ziyade bir Boolean ifadesine dayanır. İçin
Bu durumlarda, mantıksal olarak kontrol edilen bir döngü uygundur. Aslında, mantıksal olarak
kontrollü döngüler, karşı kontrollü döngülerden daha geneldir. Her sayı-
ing döngüsü mantıksal bir döngü ile oluşturulabilir, ancak bunun tersi doğru değildir. Ayrıca, hatırlama
kontrol yapısını ifade etmek için sadece seçim ve mantıksal döngülerin gerekli olduğunu
herhangi bir akış şemasının
8.3.2.1 Tasarım Konuları
Sayaç kontrollü döngülerden çok daha basit oldukları için mantıksal olarak tutarlıdırlar.
Trolled döngüler daha az tasarım sorununa sahiptir.
• Kontrol ön test mi son test mi olmalı?
• Mantıksal olarak kontrol edilen döngü, sayma döngüsünün özel bir biçimi mi olmalı?
yoksa ayrı bir açıklama mı?
8.3.2.2 Örnekler
C-tabanlı programlama dilleri hem ön test hem de son test loglarını içerir.
karşı kontrollü döngülerinin özel biçimleri olmayan cally kontrollü döngüler
yinelemeli ifadeler. Ön test ve son test mantıksal döngüleri aşağıdakilere sahiptir:
formlar:
süre ( kontrol_ifadesi )
döngü gövdesi
ve
yapmak
döngü gövdesi
while ( kontrol_ifadesi );

Sayfa 390
8.3 Yinelemeli İfadeler 369
Bu iki deyim formu, aşağıdaki C# kod bölümleriyle örneklenmiştir:
toplam = 0;
indat = Int32.Parse(Console.ReadLine());
while (indat >= 0) {
toplam += indat;
indat = Int32.Parse(Console.ReadLine());
}
değer = Int32.Parse(Console.ReadLine());
yap {
değer /= 10;
rakamlar ++;
} while (değer > 0);
Bu örneklerdeki tüm değişkenlerin tamsayı türü olduğuna dikkat edin. Read-
Konsol nesnesinin satır yöntemi , klavyeden bir metin satırı alır.
Int32.Parse , dize parametresindeki sayıyı bulur, onu int'e dönüştürür
yazın ve döndürür.
Mantıksal döngünün ( while ) ön test sürümünde , deyim veya deyim
ifade doğru olarak değerlendirildiği sürece segment yürütülür. son testte
version ( do ), döngü gövdesi, ifade false olarak değerlendirilene kadar yürütülür.
do ve while arasındaki tek gerçek fark , do'nun her zaman
döngü gövdesinin en az bir kez yürütülmesine neden olur. Her iki durumda da beyan
bileşik olabilir. Bu iki durumun operasyonel semantik açıklamaları-
aşağıdaki gibidir:
sırasında
döngü:
eğer control_expression yanlıştır git dışarı
[döngü gövdesi]
döngüye git
dışarı: . . .
yapmak - süre
döngü:
[döngü gövdesi]
eğer control_expression doğrudur git döngü
Hem içine dal hem C ve C ++ yasal olduğunu iken ve do döngüsü
bedenler. C89 sürümü, kontrol için aritmetik bir ifade kullanır; C99'da ve
C++, aritmetik veya Boolean olabilir.

Sayfa 391
370
Bölüm 8 İfade Düzeyinde Kontrol Yapıları
Java'nın while ve do deyimleri, aşağıdakiler dışında C ve C++'ınkilere benzer:
kontrol ifadesi boole türünde olmalıdır ve Java'nın
bir goto, döngü gövdeleri, başlangıçları dışında hiçbir yere girilemez.
Son test döngüleri nadiren faydalıdır ve ayrıca biraz tehlikeli olabilir.
programcıların bazen döngü gövdesinin her zaman
en az bir kez yürütülmelidir. Son test denetimi yerleştirmenin sözdizimsel tasarımı
fiziksel olarak, anlamsal etkisinin olduğu döngü gövdesinden sonra, bu tür durumlardan kaçınmaya yardımcı olur.
mantık açık hale getirerek sorunları.
Bir ön test mantıksal döngü, bir ile tamamen işlevsel bir biçimde simüle edilebilir
bir sayma döngüsünü simüle etmek için kullanılana benzer özyinelemeli işlev
Bölüm 8.3.1.5'teki beyan. Her iki durumda da, döngü gövdesi bir işlev olarak yazılır.
tion. Aşağıda, simüle edilmiş bir mantıksal ön test döngüsünün genel şekli verilmiştir.
F#'da:
rec izin while döngüsü testi vücut =
eğer test() o zaman
gövde()
whileLoop test gövdesi
Başka
();
8.3.3 Kullanıcı Konumlu Döngü Kontrol Mekanizmaları
Bazı durumlarda, bir programcı için bir konum seçmesi uygundur.
döngü gövdesinin üstü veya altı dışındaki döngü kontrolü. Sonuç olarak, bazı
diller bu yeteneği sağlar. Kullanıcının bulunduğu döngü için sözdizimsel bir mekanizma
kontrol nispeten basit olabilir, bu nedenle tasarımı zor değildir. Bu tür döngüler var
sonsuz döngülerin yapısı ancak kullanıcı konumlu döngü çıkışlarını içerir. Belki
en ilginç soru, tek bir döngünün mü yoksa birkaç iç içe döngünün mi olabileceğidir.
çıkılabilir. Böyle bir mekanizma için tasarım konuları şunlardır:
• Koşullu mekanizma, çıkışın ayrılmaz bir parçası olmalı mı?
• Yalnızca bir döngü gövdesinden mi çıkılmalıdır, yoksa çevreleyen döngülerden de çıkılabilir mi?
C, C++, Python, Ruby ve C# koşulsuz etiketlenmemiş çıkışlara sahiptir ( break ).
Java ve Perl koşulsuz etiketli çıkışları (var mola Java, son Perl).
Aşağıda, Java'da bir aranın olduğu iç içe döngülere bir örnek verilmiştir.
iç içe döngüden dış döngüden:
dışDöngü:
for (satır = 0; satır < numRows; satır++)
for (col = 0; col < numCols; col++) {
toplam += mat[satır][sütun];
if (toplam > 1000.0)
dış Döngüyü kırmak ;
}

Sayfa 392
8.3 Yinelemeli İfadeler 371
C, C++ ve Python, etiketlenmemiş bir kontrol ifadesi içerir, devam et ,
kontrolü, en küçük çevreleyen döngünün kontrol mekanizmasına aktarır.
Bu bir çıkış değil, daha çok döngüdeki geri kalan ifadeleri atlamanın bir yoludur.
döngü yapısını sonlandırmadan geçerli yineleme. Örneğin, düşünün
devamındaki:
while (toplam < 1000) {
getnext(değer);
Eğer (değer <0) devam ;
toplam += değer;
}
Negatif bir değer, atama ifadesinin atlanmasına neden olur ve kontrol
bunun yerine döngünün tepesindeki koşulluya aktarılır. Diğer taraftan, başka bir açıdan
el, içinde
while (toplam < 1000) {
getnext(değer);
if (değer < 0) break ;
toplam += değer;
}
negatif bir değer döngüyü sonlandırır.
Hem son hem de ara , döngülerden birden fazla çıkış sağlar;
okunabilirlik için biraz engel gibi görünüyor. Ancak olağandışı koşullar
döngü sonlandırmasını gerektiren durumlar o kadar yaygındır ki, böyle bir ifade
haklı. Ayrıca, okunabilirlik ciddi şekilde zarar görmez, çünkü tar-
tüm bu tür döngü çıkışlarının alınması, döngüden sonraki ilk ifadedir (veya çevreleyen bir
döngü) programın herhangi bir yerinde değil. Son olarak, alternatif
birden fazla döngü seviyesi bırakmak için birden fazla ara kullanmak çok daha kötü
okunabilirlik için.
Kullanıcı konumlu döngü çıkışlarının motivasyonu basittir: Bunlar, ortak bir
son derece kısıtlı bir şube deyimi aracılığıyla goto deyimlerine duyulan ihtiyaç. bu
bir goto hedefi, programda hem yukarıda hem de aşağıda birçok yer olabilir.
kendine gel. Ancak, kullanıcı konumlu döngü çıkışlarının hedefleri aşağıdaki değerin altında olmalıdır.
exit ve yalnızca bir bileşik ifadenin sonunu hemen takip edebilir.
8.3.4 Veri Yapılarına Dayalı Yineleme
Fortran'daki bir Do ifadesi, tamsayı değerleri üzerinde basit bir yineleyici kullanır. Sınav için-
lütfen, aşağıdaki ifadeyi dikkate alın:
Saymak = 1, 9, 2
Bu ifadede 1 , Count öğesinin ilk değeridir , 9 son değerdir ve
değerler arasındaki adım boyutu 2'dir . Bir dahili işlev, yineleyici çağrılmalıdır.

Sayfa 393
372
Bölüm 8 İfade Düzeyinde Kontrol Yapıları
her bir tekrar bir sonraki değerini hesaplamak için Kont eklenerek ( 2 sonuncu
Bu örnekte Count değeri ) ve yinelemenin devam edip etmeyeceğini test edin.
Python'da aynı döngü aşağıdaki gibi yazılabilir:
[0, 9, 2] aralığındaki sayım için :
Bu durumda, yineleyici aralık olarak adlandırılır . Bu döngüsel ifadeler sırasında
genellikle diziler üzerinde yineleme yapmak için kullanılır, aralarında hiçbir bağlantı yoktur.
yineleyici ve dizi.
Ada, bir döngü yineleyici aralığına ve bir dizinin alt simge aralığına izin verir
alt aralıklarla bağlanmalıdır. Örneğin, bir alt aralık tanımlanabilir, örneğin
aşağıdaki deklarasyonda olduğu gibi:
alt tip MyRange olan tamsayı aralığı 0..99;
BenimDizi: dizi (MyRange) arasında bir tamsayı;
için Endeksinde de MyRange döngü
. . .
son döngü ;
MyRange alt türü hem diziyi bildirmek hem de yineleme yapmak için kullanılır.
dizi. Bir alt aralık kullanıldığında, bir dizin aralığı taşması mümkün değildir.
yol.
Genel bir veri tabanlı yineleme ifadesi, kullanıcı tanımlı bir veri yapısı kullanır
ve yapının elemesinden geçmek için kullanıcı tanımlı bir işlev (yineleyici)
mentler. Yineleyici, her yinelemenin başında çağrılır ve her
çağrıldığında, yineleyici bazı durumlarda belirli bir veri yapısından bir öğe döndürür.
özel sipariş. Örneğin, bir programın kullanıcı tanımlı bir ikili ağacı olduğunu varsayalım.
veri düğümlerinin sayısı ve her düğümdeki veriler belirli bir şekilde işlenmelidir.
Emir. Ağaç için kullanıcı tanımlı bir yineleme ifadesi,
her yineleme için bir tane olmak üzere ağaçtaki düğümleri işaret edecek döngü değişkeni. İlk
kullanıcı tanımlı yineleme ifadesinin yürütülmesi için özel bir çağrı yapılması gerekir.
ilk ağaç öğesini almak için yineleyici. Yineleyici her zaman hatırlamalıdır
herhangi bir düğümü ziyaret etmeden tüm düğümleri ziyaret etmesi için en son hangi düğümü sunduğu
birden fazla. Dolayısıyla bir yineleyici tarihe duyarlı olmalıdır. Kullanıcı tanımlı bir yineleme-
tion ifadesi, yineleyici daha fazla öğe bulamadığında sona erer.
İçin onun büyük esneklik C tabanlı dillerin açıklamada,
kullanıcı tanımlı bir yineleme ifadesini simüle etmek için kullanılabilir. Bir kez daha, varsayalım
bir ikili ağacın düğümleri işlenecektir. Ağaç köküne bir değişken tarafından işaret ediliyorsa
root olarak adlandırılır ve travers , parametresini
Bir ağacın sonraki elemanı, istenen sırada aşağıdakiler kullanılabilir:
for (ptr = kök; ptr == boş; ptr = travers(ptr)) {
. . .
}
Bu ifadede, travers yineleyicidir.

Sayfa 394
8.3 Yinelemeli İfadeler 373
PHP'nin benzersiz öğelerine yinelemeli erişim sağlamak için önceden tanımlanmış yineleyiciler kullanılır.
diziler. Mevcut elemanında işaretçi noktaları son itera- erişilen
tion. Bir sonraki iterasyon hareket mevcut dizideki bir sonraki elemana. bu
önceki yineleyici, akımı önceki öğeye taşır . akım ayarlanabilir veya
sıfırlama operatörü ile dizinin ilk öğesine sıfırlayın . Aşağıdaki kod
$list sayı dizisinin tüm öğelerini görüntüler :
$listeyi sıfırla ;
print ("Birinci sayı: " + mevcut ($list) + "<br />");
while ($current_value = sonraki ($list))
print ("Sonraki sayı: " + $geçerli_değer + "<br \>");
Kullanıcı tanımlı yineleme ifadeleri nesneye yönelik olarak daha önemlidir
önceki yazılım geliştirme paradigmalarında olduğundan daha fazla programlama,
çünkü nesne yönelimli programlama kullanıcıları rutin olarak soyut veri türlerini kullanır
veri yapıları, özellikle koleksiyonlar için. Bu gibi durumlarda, kullanıcı tanımlı bir yineleme
ifadesi ve yineleyicisi, veri soyutlamasının yazarı tarafından sağlanmalıdır.
çünkü türdeki nesnelerin gösterimi kullanıcı tarafından bilinmez.
Java 5.0'da for ifadesinin geliştirilmiş bir sürümü Java'ya eklendi.
Bu ifade, bir dizideki değerler veya içindeki nesneler arasında yinelemeyi basitleştirir.
Yinelenebilir arabirimi uygulayan bir koleksiyon . (Önceden tanımlanmış tüm
Java'daki genel koleksiyonlar Iterable öğesini uygular .) Örneğin, bir
Dizi Listesi
myList of string adlı 5 koleksiyon , aşağıdaki ifade
her birini myElement olarak ayarlayarak tüm öğelerini yineler :
for (String myElement : myList) { . . . }
Bu yeni ifade, ayrılmış kelimesi olmasına rağmen "foreach" olarak anılır.
için .
C# ve F# (ve diğer .NET dilleri) ayrıca genel kitaplık sınıflarına sahiptir.
koleksiyonlar için. Örneğin, listeler için genel koleksiyon sınıfları vardır.
dinamik uzunluklu diziler, yığınlar, kuyruklar ve sözlüklerdir (karma tablo). Herşey
Bu önceden tanımlanmış genel koleksiyonlardan bazıları, kullanılan yerleşik yineleyicilere sahiptir.
örtük olarak foreach ifadesiyle. Ayrıca, kullanıcılar kendi tanımlayabilir
kendi koleksiyonlarına sahiptir ve IEnu'yu uygulayabilen kendi yineleyicilerini yazar.
Bu koleksiyonlarda foreach kullanımını sağlayan merator arayüzü .
Örneğin, aşağıdaki C# kodunu göz önünde bulundurun:
List<String> name = new List<String>();
isimler.Add("Bob");
isimler.Add("Karol");
isimler.Add("Ali");
. . .
5. Bir ArrayList, aslında dinamik uzunlukta bir dizi olan önceden tanımlanmış genel bir koleksiyondur.
depolamak için ilan edilen tür ne olursa olsun.

Sayfa 395
374
Bölüm 8 İfade Düzeyinde Kontrol Yapıları
foreach (string adı içinde adlar)
Console.WriteLine(isim);
Ruby'de bir blok , parantezler veya do ile sınırlandırılmış bir kod dizisidir.
ve ayrılmış sözcükleri sonlandırın . Bloklar, özel olarak yazılmış yöntemlerle kullanılabilir.
veri yapıları için yineleyiciler de dahil olmak üzere birçok yararlı yapı oluşturun. bu kon-
struct, bir blok tarafından takip edilen bir yöntem çağrısından oluşur. Bir blok aslında bir anonim-
(çağrısı kendisinden önce gelen) yönteme parametre olarak gönderilen mous yöntemi.
Çağrılan yöntem daha sonra çıktı veya nesneler üretebilen bloğu çağırabilir.
Ruby, zamanlar ve upto gibi çeşitli yineleme yöntemlerini önceden tanımlar .
karşı kontrollü döngüler ve her biri dizilerin ve karmaların basit yinelemeleri için.
Örneğin, kullanmanın şu örneği düşünün kez :
>> 4.times {"Hey!" yazar}
Hey!
Hey!
Hey!
Hey!
=> 4
Not o >> interaktif Yakut tercümanın istemi ve => kullanılır
ifadenin dönüş değerini belirtmek için. Yakut koyar deyimi dis-
parametresini oynatır. Bu örnekte, times yöntemi nesne 4'e gönderilir ,
parametre olarak gönderilen blok ile. Zaman yöntem blok çağırır
dört kez çıktı, dört satır çıktı. Hedef nesne, 4 ,
zamanlardan dönüş değeri .
En yaygın Ruby yineleyicisi , genellikle her
diziler aracılığıyla ve her öğeye bir blok uygulayın. 6 Bu amaçla,
Blokların varsa parametrelere sahip olmasına izin vermekten kaçınır.
dikey çubuklarla () sınırlandırılmış bloğun başlangıcı. Aşağıdaki örnek,
bir blok parametresi kullanan, her birinin kullanımını gösterir :
>> liste = [2, 4, 6, 8]
=> [2, 4, 6, 8]
>> list.each {|değer| değer verir}
2
4
6
8
=> [2, 4, 6, 8]
Bu örnekte, bloğun bağlı olduğu dizinin her bir elemanı için blok çağrılır.
her yöntem gönderilir. Blok, aşağıdakilerin bir listesi olan çıktıyı üretir.
dizinin elemanları. Her birinin dönüş değeri , gönderildiği dizidir.
6. Bu, Bölüm 15'te tartışılan harita işlevlerine benzer.

Sayfa 396
8.4 Koşulsuz Dallanma 375
Ruby, bir sayma döngüsü yerine upto yöntemine sahiptir. Örneğin, biz
aşağıdakilere sahip olabilir:
1.upto(5) {|x| x yazdır, " "}
Bu, aşağıdaki çıktıyı üretir:
1 2 3 4 5
Diğer dillerde for döngüsüne benzeyen sözdizimi de kullanılabilir,
aşağıdaki gibi:
1.5'te x için
x yazdır, " "
son
Ruby'nin aslında for ifadesi yoktur —yukarıdaki gibi yapılar dönüştürülür
Ruby tarafından upto yöntem çağrılarına.
Şimdi blokların nasıl çalıştığını düşünüyoruz. Verim deyimi a benzer
yöntem çağrısı, ancak alıcı nesnesi yoktur ve çağrı bir istektir.
bir yöntem çağrısı yerine yöntem çağrısına eklenen bloğu yürütün.
verim yalnızca bir blokla çağrılan bir yöntemde çağrılır. Eğer
Blok parametreleri, bu parantez içinde belirtilen sahip verim devlet
ment. Bir blok tarafından döndürülen değer, değerlendirilen son ifadenin değeridir.
blokta. Yerleşik yineleyicileri uygulamak için kullanılan bu işlemdir,
zamanlar gibi .
8.4 Koşulsuz Dallanma
Bir koşulsuz dalı deyimi belirli aktarır yürütme kontrolü
programdaki yeri. Son zamanlarda dil tasarımında en hararetli tartışma
1960'lar, koşulsuz dallanmanın bir parçası olup olmayacağı konusu üzerindeydi.
herhangi bir üst düzey dil ve eğer öyleyse, kullanımının kısıtlanıp kısıtlanmaması gerekip gerekmediği. bu
koşulsuz dal veya goto, kontrol etmek için en güçlü ifadedir.
bir programın ifadelerinin yürütme akışı. Ancak, goto care kullanmak-
daha az ciddi sorunlara yol açabilir. Goto'nun çarpıcı bir gücü var ve harika
esneklik (diğer tüm kontrol yapıları goto ve bir seçici ile oluşturulabilir),
ama kullanımını tehlikeli kılan bu güçtür. Kullanım kısıtlaması olmaksızın,
dil tasarımı veya programlama standartları tarafından dayatılan, goto ifadeleri
programların okunmasını çok zorlaştırabilir ve sonuç olarak son derece güvenilmez ve
bakımı maliyetli.
Bu sorunlar, doğrudan bir goto'nun herhangi bir şeyi zorlama yeteneğinden kaynaklanmaktadır.
ne olursa olsun, yürütme sırasındaki herhangi bir diğerini takip etmek için program deyimi
bu ifadenin daha önce yürütülen ifadeden önce mi yoksa sonra mı geldiği
metinsel sırayla. Okunabilirlik, ifadelerin yürütme sırası şu olduğunda en iyisidir.

Sayfa 397
376
Bölüm 8 İfade Düzeyinde Kontrol Yapıları
neredeyse göründükleri sırayla aynı - bizim durumumuzda,
bu, yukarıdan aşağıya anlamına gelir;
alıştık. Böylece, transfer yapabilmeleri için goto'ları kısıtlamak
bir programda yalnızca aşağı doğru kontrol, sorunu kısmen hafifletir.
lem. Goto'ların kod bölümleri etrafında kontrolü aktarmasına izin verir.
hatalara veya olağandışı koşullara yanıt verir, ancak bunların kullanımına izin vermez
herhangi bir döngü oluşturmak için.
Birkaç dil, bir goto olmadan tasarlanmıştır;
örneğin, Java, Python ve Ruby. Ancak şu anda çoğu
popüler diller bir goto ifadesi içerir. Kernighan ve
Ritchie (1978) git'i sınırsızca suistimal edilebilir olarak adlandırır, ancak bu asla-
bununla birlikte Ritchie'nin dili C'ye dahildir.
ek kontrol ifadeleri sağladıklarını ortadan kaldırdı,
genellikle döngü çıkışları şeklinde, kodlardan birini haklı çıkarmak için
goto uygulamaları.
Nispeten yeni bir dil olan C#, bir goto içerir, hatta
dayandığı dillerden biri olan Java olmasa da.
C#'ın goto'sunun meşru bir kullanımı, switch deyiminde olduğu gibi
Bölüm 8.2.2.2'de tartışılmıştır.
Bölüm 8.3.3'te açıklanan tüm döngü çıkış deyimleri
aslında kamufle edilmiş goto ifadeleridir. Ancak onlar,
ciddi şekilde kısıtlanmış gotolar ve okunabilirliğe zararlı değildir. İçinde
Aslında, okunabilirliği artırdıkları iddia edilebilir, çünkü
dolambaçlı ve doğal olmayan kodda kullanım sonuçlarından kaçının
anlamak çok daha zor olurdu.
8.5 Korunan Komutlar
Yeni ve oldukça farklı seçim biçimleri ve döngü yapıları önerildi.
Dijkstra (1975) tarafından. Birincil motivasyonu, kontrol ifadeleri sağlamaktı.
doğruluğu sağlayan bir program tasarım metodolojisini destekleyecek
tamamlanmış pro-
gram. Bu metodoloji Dijkstra'da (1976) açıklanmıştır. Başka bir motivasyon-
korunan komutlar geliştirmenin amacı, nondeterminizmin bazen
Bölüm 13'te tartışılacağı gibi, eşzamanlı programlarda ihtiyaç duyulan
Motivasyon, muhakemede dikkatli olunmasıyla mümkün olan artan netliktir.
komutlar. Basitçe söylemek gerekirse, bir seçim ifadesinin seçilebilir bir
korumalı komut ifadesi, diğerlerinden bağımsız olarak kabul edilebilir.
com'un seçim ifadeleri için doğru olmayan ifadenin bir kısmı
mon programlama dilleri.
Korumalı komutlar, temel oldukları için bu bölümde ele alınmıştır.
daha sonra eşzamanlı programlama için geliştirilen iki dilsel mekanizma için
iki dil, CSP (Hoare, 1978) ve Ada. Ada'da eşzamanlılık tartışılıyor
Bölüm 13'te. Korunan komutlar ayrıca Haskell'deki işlevleri tanımlamak için kullanılır,
Bölüm 15'te tartışıldığı gibi.
tarih notu
Birkaç düşünceli olmasına rağmen
insanlar onlara kulak-
yalan söyleyen, Edsger Dijkstra'ydı.
bilgisayar dünyasına verdi
ilk geniş çapta okunan ifşa
gitmenin tehlikeleri. mektubunda
"Goto ifadesi
olduğu gibi sadece çok ilkel;
bu çok fazla bir davet
birinin programını bozmak”
(Dijkstra, 1968a). Sırasında
yayınlandıktan sonraki ilk birkaç yıl
Dijkstra'nın goto hakkındaki görüşlerinin,
çok sayıda insan tartıştı
her ikisi için de halka açık
sürgün veya en azından kısıtlama-
goto kullanımına ilişkin açıklamalar.
Beğenmeyenler arasında
tam eliminasyon Don-
tartışan ald Knuth (1974),
öyle durumlar oldu ki
çıkışın verimliliği-
okunabilirliğe verdiği zararı tarttı.

Sayfa 398
8.5 Korunan Komutlar 377
Dijkstra'nın seçim bildirimi şu şekildedir:
if < Boole ifadesi > -> < deyimi >
[] < Boole ifadesi > -> < deyimi >
[] . . .
[] < Boole ifadesi > -> < deyimi >
fi
Kapanış ayrılmış sözcüğü fi , geri yazılan açılış ayrılmış sözcüktür.
koğuş. Bu rezerve edilmiş kelime kapatma şekli ALGOL 68'den alınmıştır.
fatbars adı verilen bloklar, korunan cümleleri ayırmak ve izin vermek için kullanılır.
cümlecikler deyim dizileri olsun. Seçim ifadesindeki her satır,
Boole ifadesinin (koruyucu) ve bir ifadenin veya ifade dizisinin oluşturulması,
korunan komut olarak adlandırılır .
Bu seçim ifadesi çoklu seçim görünümündedir, ancak
semantik farklıdır. Boolean ifadelerinin tümü, her seferinde değerlendirilir.
deyimi yürütme sırasında ulaşılır. Birden fazla ifade doğruysa, bir
karşılık gelen ifadelerden bazıları, yürütme için deterministik olmayan bir şekilde seçilebilir.
tion. Bir uygulama her zaman ile ilişkili ifadeyi seçebilir.
true olarak değerlendirilen ilk Boole ifadesi. Ama herhangi bir ifadeyi seçebilir
gerçek bir Boole ifadesi ile ilişkilendirilir. Yani programın doğruluğu
hangi ifadenin seçildiğine bağlı olamaz (doğru ile ilişkili olanlar arasında
Boole ifadeleri). Boolean ifadelerinin hiçbiri doğru değilse, bir çalışma zamanı
programın sonlandırılmasına neden olan bir hata oluşur. Bu, programcıyı
tüm olasılıkları düşünün ve listeleyin. Aşağıdaki örneği göz önünde bulundurun:
eğer i = 0 -> toplam := toplam + i
[] ben > j -> toplam := toplam + j
[] j > ben -> toplam := toplam + ben
fi
Eğer ben 0 = ve j> i , bu açıklama arasında nondeterministically seçer
birinci ve üçüncü atama ifadeleri. Eğer ben eşittir j ve sıfır, bir çalıştırıcı değil
koşulların hiçbiri doğru olmadığı için zaman hatası oluşur.
Bu ifade, programcının şunları belirtmesine izin vermenin zarif bir yolu olabilir.
bazı durumlarda yürütme sırasının önemsiz olduğunu. Örneğin, bulmak için
kullanabileceğimiz iki sayıdan en büyüğü
if x >= y -> maks := x
[] y >= x -> maks := y
fi
Bu, çözümü aşırı belirtmeden istenen sonucu hesaplar. Eşit-
eğer ticular, x ve y eşit durumda olduğunu atamak hangi önemli değil max . Bu
deterministik olmayan semantiği tarafından sağlanan bir soyutlama biçimidir.
Beyan.

Sayfa 399
378
Bölüm 8 İfade Düzeyinde Kontrol Yapıları
Şimdi, geleneksel bir programlama dilinde kodlanmış aynı işlemi düşünün.
seçici:
eğer (x >= y)
maksimum = x;
Başka
maksimum = y;
Bu da şu şekilde kodlanabilir:
Eğer (x> y)
maksimum = x;
Başka
maksimum = y;
Bu iki ifade arasında pratik bir fark yoktur. ilk atamalar
X için maksimum X ve Y eşittir; İkinci atar y için maksimum aynı olarak
durum. İki ifade arasındaki bu seçim, resmi ifadeyi karmaşıklaştırır.
kodun analizi ve doğruluğunun kanıtı. Bu sebeplerden biri
korumalı komutlar neden Dijkstra tarafından geliştirildi.
Dijkstra tarafından önerilen döngü yapısı şu şekildedir:
do < Boole ifadesi > -> < deyimi >
[] < Boole ifadesi > -> < deyimi >
[] . . .
[] < Boole ifadesi > -> < deyimi >
od
Bu ifadenin anlamı, tüm Boolean ifadelerinin değerlendirilmesidir.
her yinelemede. Birden fazla doğruysa, ilişkili ifadelerden biri
yürütme için deterministik olmayan (belki de rastgele) seçilir, bundan sonra
ifadeler tekrar değerlendirilir. Tüm ifadeler aynı anda olduğunda
false, döngü sona erer.
Aşağıdaki problemi göz önünde bulundurun: Verilen dört tamsayı değişkeni, q1 , q2 , q3 ,
ve q4 , dördünün değerlerini q1 ≤ q2 ≤ q3 ≤ q4 olacak şekilde yeniden düzenleyin . Olmadan
korunan komutlar, basit bir çözüm, dört değeri
bir dizi, diziyi sıralayın ve ardından dizideki değerleri tekrar diziye atayın.
skaler değişkenler q1 , q2 , q3 ve q4 . Bu çözüm zor olmasa da
özellikle sıralama işleminin dahil edilmesi gerekiyorsa, çok sayıda kod gerektirir.
Şimdi, çözmek için korumalı komutları kullanan aşağıdaki kodu göz önünde bulundurun.
aynı problem ama daha özlü ve zarif bir şekilde. 7
yap q1 > q2 -> sıcaklık := q1; q1 := q2; q2 := sıcaklık;
[] q2 > q3 -> sıcaklık := q2; q2 := q3; q3 := sıcaklık;
7. Bu kod, Dijkstra'da (1975) biraz farklı bir biçimde görünür.

Sayfa 400
8.6 Sonuçlar 379
[] q3 > q4 -> sıcaklık := q3; q3 := q4; q4 := sıcaklık;
od
Dijkstra'nın korumalı komuta kontrol ifadeleri kısmen ilginçtir.
çünkü ifadelerin sözdiziminin ve anlambiliminin nasıl bir
program doğrulama üzerinde etkisi ve tersi. Program doğrulama sanal olarak
goto ifadeleri kullanıldığında imkansızdır. Doğrulama, aşağıdaki durumlarda büyük ölçüde basitleştirilmiştir:
(1) yalnızca mantıksal döngüler ve seçimler kullanılır veya (2) yalnızca korunan komutlar kullanılır
kullanılmış. Korunan komutların aksiyomatik semantiği uygun bir şekilde özeldir.
(Gries, 1981). Bununla birlikte, önemli ölçüde var olduğu açık olmalıdır.
üzerinde korunan komutların uygulanmasında artan karmaşıklık
geleneksel deterministik muadilleri.
8.6 Sonuçlar
Çeşitli deyim düzeyinde kontrol yapılarını tanımladık ve tartıştık.
Şimdi kısa bir değerlendirme uygun görünüyor.
İlk olarak, yalnızca dizi, seçim ve ön-
hesaplamaları ifade etmek için mantıksal döngüleri test etmek kesinlikle gereklidir (Böhm ve
Jakopini, 1966). Bu sonuç, kural dışılığı yasaklamak isteyenler tarafından kullanılmıştır.
tamamen dallanma. Tabii ki, zaten yeterince pratik var
teorik bir sebep de kullanmadan onu kınamakla ilgili sorunlar.
Goto'ların temel meşru ihtiyaçlarından biri olan döngülerden erken çıkışlar,
break gibi son derece kısıtlı dal ifadeleriyle karşılanabilir .
Böhm ve Jacopini sonucunun bariz bir kötüye kullanımı,
seçimin ötesinde herhangi bir kontrol yapısının dahil edilmesi ve mantıksal ön test
döngüler. Yaygın olarak kullanılan hiçbir dil henüz bu adımı atmamıştır; ayrıca şüphemiz var
yazılabilirlik ve okunabilirlik üzerindeki olumsuz etki nedeniyle, herhangi bir zaman olacak.
Yalnızca seçim ve ön test mantıksal döngüleriyle yazılan programlar genellikle
yapısı daha az doğal, daha karmaşık ve bu nedenle yazması daha zor ve
okumak daha zor. Örneğin, C# çoklu seçim yapısı bir
bariz bir olumsuzluk olmadan C# yazılabilirliğinde büyük artış. Başka bir örnek
birçok dilin sayma döngüsü yapısı, özellikle ifade
Ada'da olduğu gibi basittir.
Diğer kontrol yapılarının çoğunun faydası o kadar açık değildir.
önerilenler dillere dahil edilmeye değerdir (Ledgard ve
Marcoty, 1975). Bu soru büyük ölçüde temel sorulara dayanmaktadır.
dillerin boyutunun en aza indirilmesi gerekip gerekmediği. Her ikisi de Wirth (1975)
ve Hoare (1973) dil tasarımında basitliği kuvvetle desteklemektedir. Bu durumuda
kontrol yapıları, basitlik, sadece birkaç kontrol ifadesinin olması gerektiği anlamına gelir.
bir dilde olmalı ve basit olmalıdırlar.
deyim düzeyinde kontrol yapılarının zengin çeşitliliği,
icat, dil tasarımcıları arasındaki fikir çeşitliliğini gösterir. Nihayet
buluş, tartışma ve değerlendirme, hala fikir birliği yok
bir dilde olması gereken kesin kontrol ifadeleri kümesinde. Çoğu

Sayfa 401
380
Bölüm 8 İfade Düzeyinde Kontrol Yapıları
Çağdaş diller elbette benzer kontrol ifadelerine sahiptir, ancak
sözdizimlerinin ve anlambilimlerinin ayrıntılarında hala bazı farklılıklar vardır. Kürk-
termore, bir dilin bir dil içermesi gerekip gerekmediği konusunda hala anlaşmazlık var.
git; C++ ve C# yapar, ancak Java ve Ruby yapmaz.
ÖZET
Kontrol ifadeleri birkaç kategoride ortaya çıkar: seçim, çoklu seçim,
yinelemeli ve koşulsuz dallanma.
Anahtar C tabanlı dillerin ifadesi temsilcisidir
çoklu seçim ifadeleri C# sürümü güvenilirliği ortadan kaldırır
Bir
seçilen segmenti aşağıdaki seçilebilir segmente
Yüksek için çok sayıda farklı döngü ifadesi icat edilmiştir.
seviye dilleri. Ada'nın for ifadesi, karmaşıklık açısından tam tersidir. o
yalnızca en çok ihtiyaç duyulan sayma döngüsü formlarını zarif bir şekilde uygular.
C'nin for ifadesi, esnek olmasına rağmen en esnek yineleme ifadesidir.
yetkinlik bazı güvenilirlik sorunlarına yol açar.
Çoğu dilin döngüleri için çıkış deyimleri vardır; bu ifadeler
goto deyimlerinin en yaygın kullanımlarından birinin yeri.
Veri tabanlı yineleyiciler, veri yapılarını işlemek için döngü ifadeleridir.
bağlantılı listeler, karmalar ve ağaçlar olarak. İçin C tabanlı dillerin açıklamada
kullanıcının, kullanıcı tanımlı veriler için yineleyiciler oluşturmasına olanak tanır. foreach ifadesi
Perl ve C#, standart veri yapıları için önceden tanımlanmış bir yineleyicidir. içinde
geçici nesne yönelimli diller, koleksiyonlar için yineleyiciler ile belirtilir
koleksiyon tasarımcıları tarafından uygulanan standart arayüzler.
Ruby, gönderilen yöntemlerin özel bir biçimi olan yineleyicileri içerir.
çeşitli nesneler. Dil, ortak kullanımlar için yineleyicileri önceden tanımlar, ancak aynı zamanda
kullanıcı tanımlı yineleyicilere izin verir.
Koşulsuz dal veya git, en zorunlu dilin bir parçası olmuştur.
göstergeler. Sorunları geniş çapta tartışıldı ve tartışıldı. Mevcut
fikir birliği, çoğu dilde kalması gerektiği, ancak tehlikelerinin
programlama disiplini ile en aza indirilebilir.
Dijkstra'nın korumalı komutları, konumlu alternatif kontrol ifadeleridir.
tif teorik özellikler. olarak kabul edilmemesine rağmen
Bir dilin kontrol ifadeleri, anlambilimin bir kısmı eşzamanlı olarak görünür.
CSP ve Ada'nın rency mekanizmaları ve Haskell'in fonksiyon tanımları.
İNCELEME SORULARI
1. Kontrol yapısının tanımı nedir ?
2. Böhm ve Jocopini akış şemaları hakkında neyi kanıtladı?

Sayfa 402
Soruları gözden geçir 381
3. Block'nin tanımı nedir ?
4. Tüm seçim ve yineleme kontrolü için tasarım sorunları nelerdir?
ifadeler?
5. Seçim yapıları için tasarım konuları nelerdir?
6. Python'un bileşik ifade tasarımında olağandışı olan nedir?
7. Hangi koşullar altında bir F# seçicisinin else yan tümcesi olmalıdır?
8. İki yönlü yuvalama sorununun ortak çözümleri nelerdir?
seçiciler?
9. Çoktan seçmeli ifadeler için tasarım sorunları nelerdir?
10. Hangi iki dil özelliği arasında ne zaman bir takas yapılır?
birden fazla seçilebilir segmentin tek seferde yürütülüp yürütülmediğine karar vermek
çoklu seçim ifadesinin yürütülmesi?
11. C'nin çoktan seçmeli ifadesinde olağandışı olan nedir?
12. C'nin switch ifadesi hangi önceki dile dayanıyordu?
13. C#'ın switch ifadesinin C'ninkinden nasıl daha güvenli olduğunu açıklayın.
14. Tüm yinelemeli kontrol ifadeleri için tasarım sorunları nelerdir?
15. Sayaç kontrollü döngü ifadeleri için tasarım sorunları nelerdir?
16. Ön test döngü ifadesi nedir? Sontest döngü ifadesi nedir?
17. C++' ın for deyimi ile Java'nınki arasındaki fark nedir ?
18. C for deyimi diğer birçok ifadeden ne şekilde daha esnektir?
Diller?
19. Python'daki aralık işlevi ne işe yarar?
20. Hangi çağdaş dillerde goto bulunmaz?
21. Mantıksal olarak kontrol edilen döngü ifadeleri için tasarım sorunları nelerdir?
22. Kullanıcı konumlu döngü kontrol ifadelerinin ana nedeni nedir?
icat edildi?
23. Kullanıcı konumlu döngü kontrol mekanizmaları için tasarım sorunları nelerdir?
24. Java'nın neyi avantajı molası ifadesi C'nin üzerinde sahip aradan
Beyan?
25. C++' ın break deyimi ile bu ifade arasındaki farklar nelerdir?
Java'nın?
26. Kullanıcı tanımlı yineleme kontrolü nedir?
27. Hangi Scheme işlevi bir çoklu seçim ifadesini uygular?
28. İşlevsel bir dil tekrarı nasıl uygular?
29. Ruby'de yineleyiciler nasıl uygulanır?
30. Yineleme için açıkça çağrılabilecek yineleyicileri hangi dil önceden tanımlar?
önceden tanımlanmış veri yapıları üzerinde?
31. Hangi ortak programlama dili, tasarımının bir bölümünü ödünç alır?
Dijkstra'nın korunan komutları?

Sayfa 403
382
Bölüm 8 İfade Düzeyinde Kontrol Yapıları
PROBLEM SETİ
1. Birleştirilmiş sayma ve mantıksal döngünün birleştirildiği üç durumu tanımlayın.
beyana ihtiyaç vardır.
2. Liskov ve diğerlerinde CLU'nun yineleyici özelliğini inceleyin. (1981) ve belirlemek
avantajları ve dezavantajları.
3. Ada denetim deyimleri kümesini C#'ınkilerle karşılaştırın ve karar verin
hangileri daha iyi ve neden.
4. Eşsiz kapanış için ayrılmış kelimeler kullanmanın artıları ve eksileri nelerdir?
bileşik ifadeler?
5. Python'un girinti kullanımı için pro ve con argümanları nelerdir?
kontrol ifadelerinde bileşik ifadeler belirtilsin mi?
6. Kapatma saklı kullanımıyla ilgili olası okunabilirlik sorunlarını analiz edin
karşılık gelenlerin tersi olan kontrol ifadeleri için kelimeler
case-esac ayrılmış sözcükleri gibi ilk ayrılmış sözcükleri
ALGOL 68. Örneğin, trans-
poz veren karakterler
7. Knuth'a atıfta bulunan bir makale bulmak için Science Citation Index'i kullanın
(1974). Makaleyi ve Knuth'un makalesini okuyun ve özetleyen bir makale yazın.
goto meselesinin her iki tarafını da birleştirir.
8. Goto sorunuyla ilgili makalesinde Knuth (1974), bir döngü kontrolü önerir.
birden fazla çıkışa izin veren ifade. Gazeteyi oku ve bir opera yaz.
deyimin tional semantik açıklaması.
9. Bool-'un özel kullanımının hem lehine hem de aleyhine olan argümanlar nelerdir?
Java'daki kontrol ifadelerindeki ean ifadeleri (aynı zamanda
C++'da olduğu gibi aritmetik ifadelere izin vermek)?
10. Ada'da, vaka bildiriminin seçim listeleri kapsamlı olmalıdır, böylece
kontrol ifadesinde temsil edilmeyen değerler olamaz. C++'da,
temsil edilmeyen değerler, varsayılan seçim ile çalışma zamanında yakalanabilir.
tor. Varsayılan yoksa, temsil edilmeyen bir değer bütüne neden olur.
atlanması gereken açıklama. Bu iki tasarımın artıları ve eksileri nelerdir?
(Ada ve C++)?
11. Java for ifadesinin avantaj ve dezavantajlarını açıklayın ,
Ada'nın kıyasla For .
12. Python'daki else yan tümcesinin kullanıldığı bir programlama durumunu tanımlayın.
için açıklamada uygun olacaktır.
13. Son test gerektiren üç özel programlama durumunu tanımlayın
döngü.
14. Kontrolün bir C döngüsüne neden aktarılabileceği konusunda tahminde bulunun
Beyan.

Sayfa 404
Programlama Alıştırmaları 383
PROGRAMLAMAALIŞTIRMALAR
1. Aşağıdaki sözde kod parçasını, bir döngü yapısı kullanarak yeniden yazın.
belirtilen diller:
k = (j + 13) / 27
döngü:
eğer k> 10 sonra goto, dışarı
k = k + 1
ben = 3 * k - 1
döngüye git
dışarı: . . .
a. 95
B. Ada
C. C, C++, Java veya C#
D. piton
e. yakut
Tüm değişkenlerin tamsayı türü olduğunu varsayın. Bunun için hangi dili tartışın
en iyi yazılabilirliğe, en iyi okunabilirliğe ve en iyi kombinasyona sahiptir.
ikisinin konusu.
2. Programlama Alıştırma 1'i Yeniden Yapın, bu sefer tüm değişkenleri yapın
ve kayan nokta türünü sabitler ve ifadeyi değiştirir
k = k + 1
ile
k = k + 1.2
3. Bir çoklu seçim ifadesi kullanarak aşağıdaki kod parçasını yeniden yazın
aşağıdaki dillerde:
if ((k == 1) || (k == 2)) j = 2 * k - 1
if ((k == 3) || (k == 5)) j = 3 * k + 1
if (k == 4) j = 4 * k - 1
if ((k == 6) || (k == 7) || (k == 8)) j = k - 2
a. Fortran 95 (muhtemelen buna bakmanız gerekecek)
B. Ada
C. C, C++, Java veya C#

Sayfa 405
384
Bölüm 8 İfade Düzeyinde Kontrol Yapıları
D. piton
e. yakut
Tüm değişkenlerin tamsayı türü olduğunu varsayın. göreli yararlarını tartışın.
bu özel kod için bu dillerin kullanımı.
4. Aşağıdaki C program segmentini göz önünde bulundurun. Goto kullanmadan yeniden yazın veya
ara verir .
j = -3;
for (i = 0; i < 3; i++) {
anahtar (j + 2) {
durum 3:
durum 2: j--; ara ;
durum 0: j += 2; ara ;
varsayılan : j = 0;
}
eğer (j > 0) kırılırsa ;
j = 3 - ben
}
5. Rubin (1987) CACM editörüne yazdığı bir mektupta aşağıdaki kodu kullanır.
segmenti, gotos içeren bazı kodların okunabilirliğinin bahis-
ter, gotos içermeyen eşdeğer koddan daha fazla. Bu kod ilk satırı bulur
Bir arasında n ile n, tam sayı matris adlı x başka bir şey sıfır değerleri vardır.
for (i = 1; i <= n; i++) {
için (J <= N; j ++ J = 1)
eğer (x[i][j] != 0)
reddetmeye git ;
println ('İlk tamamı sıfır olan satır:', i);
ara ;
reddetmek:
}
Bu kodu, aşağıdaki dillerden birinde gotos olmadan yeniden yazın: C,
C++, Java, C# veya Ada. Kodunuzun okunabilirliğini, kodunuzun okunabilirliğiyle karşılaştırın.
örnek kod.
6. Aşağıdaki programlama problemini göz önünde bulundurun:
ger değişkenleri - birinci , ikinci ve üçüncü - üçe yerleştirilmelidir
max , mid ve min değişkenleri , bariz anlamlarıyla, kullanmadan
diziler veya kullanıcı tanımlı veya önceden tanımlanmış alt programlar. İki çözüm yazın
bu soruna, iç içe seçimleri kullanan ve kullanmayan.
İkisinin karmaşıklığını ve beklenen güvenilirliğini karşılaştırın.

Sayfa 406
Programlama Alıştırmaları 385
7. Aşağıdaki Java for ifadesini Ada'ya yazın:
int i, j, n = 100;
için (i = 0, j = 17; i < n; i++, j--)
toplam += i * j + 3;
8. Programlama Alıştırma 4'ün C program bölümünü if kullanarak yeniden yazın.
ve C'deki goto ifadeleri.
9. Java'da Programlama Alıştırma 4'ün C program segmentini yeniden yazın
Bir kullanmadan anahtar deyimi.
10. Aşağıdaki çağrıyı Scheme'in COND'una çevirin ve sonucu C'ye ayarlayın.
y'ye değer .
(KOND
((> x 10) x)
((< x 5) (* 2 x))
((= x 7) (+ x 10))
)

Sayfa 407
Bu sayfa bilerek boş bırakılmıştır

Sayfa 408
387
9.1 Giriş
9.2 Alt Programların Temelleri
9.3 Alt Programlar için Tasarım Konuları
9.4 Yerel Referans Ortamları
9.5 Parametre Geçiş Yöntemleri
9.6 Alt Program Olan Parametreler
9.7 Alt Programları Dolaylı Olarak Çağırmak
9.8 Aşırı Yüklenmiş Alt Programlar
9.9 Genel Alt Programlar
9.10 Fonksiyonlar için Tasarım Konuları
9.11 Kullanıcı Tanımlı Aşırı Yüklenmiş Operatörler
9.12 Kapanışlar
9.13 Eşyordamlar
9
alt programlar

Sayfa 409
388
Bölüm 9 Alt Programlar
S ubprograms orada-programların temel yapı taşlarıdır ve vardır
programlama dili tasarımında en önemli kavramlardan biridir. Biz
şimdi parametre geçirme yöntemi de dahil olmak üzere alt programların tasarımını keşfedin.
ods, yerel referans ortamları, aşırı yüklenmiş alt programlar, genel alt programlar,
ve alt programlarla ilişkili takma ad ve sorunlu yan etkiler.
Ayrıca dolaylı olarak adlandırılan alt programlar, kapanışlar ve eşyordamlarla ilgili tartışmaları da dahil ediyoruz.
Alt programlar için uygulama yöntemleri Bölüm 10'da tartışılmaktadır.
9.1 Giriş
Bir programlama diline iki temel soyutlama olanağı dahil edilebilir.
guage: süreç soyutlaması ve veri soyutlaması. Yüksek tarihin erken dönemlerinde
seviye programlama dilleri, sadece süreç soyutlaması dahil edildi. İşlem
alt programlar şeklinde soyutlama, tüm programlarda merkezi bir kavram olmuştur.
Programlama dilleri. Ancak 1980'lerde birçok insan inanmaya başladı.
veri soyutlaması da aynı derecede önemliydi. Veri soyutlaması şu bölümde tartışılmaktadır:
Ayrıntılar Bölüm 11'de.
İlk programlanabilir bilgisayar, Babbage's Analytical Engine, inşa edildi.
1840'larda, talimat kartları koleksiyonlarını yeniden kullanma yeteneğine sahipti.
bir programda birkaç farklı yer. Modern bir programlama dilinde,
böyle bir ifadeler koleksiyonu bir alt program olarak yazılır. Bu yeniden kullanım sonuçları
başta bellek alanı ve kodlama süresi olmak üzere birkaç farklı türde tasarruf sağlar.
Bu tür bir yeniden kullanım, aynı zamanda, alt programın bilgisayar bilgilerinin ayrıntıları için bir soyutlamadır.
bir programda alt programı çağıran bir ifade ile değiştirilir.
Bir programda bazı hesaplamaların nasıl yapılacağını açıklamak yerine,
açıklama (alt programdaki ifadelerin toplanması)
ayrıntıları etkili bir şekilde soyutlayan bir çağrı ifadesi. Bu artırır
bir programın mantıksal yapısını vurgularken aynı zamanda bir programın okunabilirliği
düşük seviyeli detaylar.
Nesne yönelimli dillerin yöntemleri, alt dillerle yakından ilişkilidir.
Bu bölümde tartışılan programlar. Birincil yol yöntemleri, alt yöntemlerden farklıdır.
programlar, adlandırılma biçimleri ve sınıflarla olan ilişkileri ve
nesneler. Yöntemlerin bu özel özellikleri tartışılsa da
Bölüm 12, alt programlarla paylaştıkları parametreler ve
yerel değişkenler, bu bölümde tartışılmaktadır.
9.2 Alt Programların Temelleri
9.2.1 Genel Alt Program Özellikleri
Bu bölümde açıklanan eşyordamlar dışında, bu bölümde tartışılan tüm alt programlar
Bölüm 9.13, aşağıdaki özelliklere sahiptir:
• Her alt programın tek bir giriş noktası vardır.

Sayfa 410
9.2 Alt Programların Temelleri 389
• Çağıran program birimi, aranan programın yürütülmesi sırasında askıya alınır.
yürütülmekte olan yalnızca bir alt program olduğunu ima eden alt program
Herhangi bir zamanda.
• Alt program yürütüldüğünde kontrol her zaman arayana döner
sona erer.
Bunların alternatifleri, eşyordamlar ve eşzamanlı birimlerle sonuçlanır (Bölüm 13).
Bazıları isimsiz olsa da çoğu alt programın isimleri vardır. Bölüm
9.12, C#'da anonim alt program örneklerine sahiptir.
9.2.2 Temel Tanımlar
Bir alt program tanımı , alt programın arayüzünü ve eylemlerini tanımlar.
program soyutlaması. Bir alt program çağrısı , belirli bir
alt program çalıştırılır. Bir alt programın, etkinleştirildikten sonra aktif olduğu söylenir.
çağrıldı, yürütmeye başladı ancak henüz bu yürütmeyi tamamlamadı. bu
iki temel alt program türü, prosedür ve fonksiyon tanımlanmıştır.
ve Bölüm 9.2.4'te tartışılmıştır.
Tanımın ilk kısmı olan bir alt program başlığı ,
birkaç amaç. İlk olarak, aşağıdaki sözdizimsel birimin bir alt program olduğunu belirtir.
belirli bir tür gram tanımı. 1 Birden fazla dili olan dillerde
alt program türü, alt programın türü genellikle bir
özel kelime. İkincisi, alt program anonim değilse, başlık şunları sağlar:
alt program için bir isim. Üçüncüsü, isteğe bağlı olarak bir liste belirtebilir.
parametreler.
Aşağıdaki başlık örneklerini göz önünde bulundurun:
def toplayıcı parametreleri ) :
Bu, adder adlı bir Python alt programının başlığıdır . Ruby alt programı
üstbilgiler de def ile başlar . JavaScript alt programının başlığı başlar
ile fonksiyonu .
C'de, toplayıcı adlı bir işlevin başlığı aşağıdaki gibi olabilir:
geçersiz toplayıcı ( parametreler )
Bu başlıktaki ayrılmış sözcük void , alt programın
bir değer döndürmez.
Alt programların gövdesi, eylemlerini tanımlar. C tabanlı dillerde
(ve diğerleri - örneğin JavaScript) bir alt programın gövdesi sınırlayıcıdır.
parantezler tarafından ted. Ruby'de bir bitiş ifadesi, bir alt programın gövdesini sonlandırır.
Bileşik deyimlerde olduğu gibi, bir Python işlevinin gövdesindeki deyimler
girintili olmalı ve gövdenin sonu ilk ifade ile belirtilmelidir.
bu girintili değil.
1. Bazı programlama dilleri, her iki tür alt programı, prosedürü ve
fonksiyonlar.

Sayfa 411
390
Bölüm 9 Alt Programlar
Python işlevlerinin onları işlevden ayıran bir özelliği,
Diğer yaygın programlama dillerinin en önemli özelliği, işlev def ifadeleridir.
yürütülebilir. Bir def deyimi yürütüldüğünde, verilen adı şuna atar.
verilen fonksiyon gövdesi. Bir fonksiyonun def'i yürütülene kadar, fonksiyon
çağrılamaz. Aşağıdaki iskelet örneğini düşünün:
eğer . . .
kesinlikle eğlence(. . .):
. . .
Başka
kesinlikle eğlence(. . .):
. . .
Bu seçim yapısının then yan tümcesi yürütülürse,
fun işlevi çağrılabilir, ancak else yan tümcesindeki sürüm çağrılmaz. Aynı şekilde, eğer
else yan tümcesi seçilirse, fonksiyonun versiyonu çağrılabilir, ancak bir
sonra yan tümcesinde olamaz.
Ruby yöntemleri, diğer programlama dillerinin alt programlarından farklıdır.
birkaç ilginç yolla ölçüyor. Ruby yöntemleri genellikle sınıfta tanımlanır
tanımlar, ancak sınıf tanımlarının dışında da tanımlanabilir, bu durumda bunlar
Object kök nesnesinin yöntemleri olarak kabul edilir . Bu tür yöntemler çağrılabilir
bir nesne alıcısı olmadan, sanki C veya C++'daki işlevlermiş gibi. Eğer bir Ruby
yöntem alıcı olmadan çağrılır, self varsayılır. tarafından herhangi bir yöntem yoksa
sınıfta adın, çevreleyen sınıflar kadar aranır Nesne gerekirse.
Senkronizasyon kullanılarak tanımlanabilmelerine rağmen tüm Lua işlevleri anonimdir.
isimleri varmış gibi görünmesini sağlayan vergi. Örneğin, şunu düşünün:
fonksiyon küpünün aşağıdaki özdeş tanımları :
fonksiyon küp(x) dönüş x * x * x bitiş
küp = fonksiyon (x) dönüş x * x * x bitiş
Bunlardan ilki geleneksel sözdizimini kullanırken, ikincisinin biçimi daha çok
fonksiyonların isimsizliğini doğru bir şekilde gösterir.
Parametre profili bir alt program içeren sayısı, düzeni ve
biçimsel parametrelerinin türleri. Protokol bir alt onun parametresidir
profile plus, eğer bir fonksiyon ise, dönüş tipi. Alt pro-
gram türleri vardır, bu türler alt programın protokolü tarafından tanımlanır.
Alt programlar, tanımların yanı sıra bildirimlere de sahip olabilir. Bu form paralel-
C'deki değişken bildirimlerini ve tanımlarını içerir;
tür bilgisi sağlamak için kullanılabilir ancak değişkenleri tanımlamak için kullanılamaz. alt program
bildirimler, alt programın protokolünü sağlar, ancak bunların gövdelerini içermez.
ies. İleriye dönük referanslara izin vermeyen dillerde gereklidirler.
alt programlar. Hem değişkenler hem de alt programlar durumunda, bildirimler
statik tip kontrolü için gereklidir. Alt programlar söz konusu olduğunda, bu, programın tipidir.
kontrol edilmesi gereken parametrelerdir. İşlev bildirimleri C'de yaygındır ve

Sayfa 412
9.2 Alt Programların Temelleri 391
Prototip olarak adlandırılan C++ programları . Bu tür beyanlar genellikle
başlık dosyalarına yerleştirilir.
Diğer dillerin çoğunda (C ve C++ dışında), alt programların
bildirimler, çünkü alt programların tanımlanması gerekliliği yoktur.
onlar çağrılmadan önce.
9.2.3 Parametreler
Alt programlar tipik olarak hesaplamaları tanımlar. olmayan iki yol vardır.
yöntem alt programı, işleyeceği verilere erişim sağlayabilir:
yerel olmayan değişkenlere doğrudan erişim (başka bir yerde bildirilmiş ancak alt
program) veya parametre geçişi yoluyla. Parametrelerden geçen veriler
alt programa yerel adlar aracılığıyla erişilir. Parametre geçişi
yerel olmayan değişkenlere doğrudan erişimden daha esnektir. Aslında, bir alt program
işleneceği verilere parametre erişimi ile parametreleştirilmiş bir işlemdir.
varsayım. Hesaplamayı, aldığı veriler üzerinden gerçekleştirebilir.
parametreleri (parametre türlerinin,
alt programı). Veri erişimi yerel olmayan değişkenler aracılığıyla ise, bunun tek yolu
hesaplama farklı veriler üzerinde devam edebilir, bunlara yeni değerler atamak
alt programa yapılan çağrılar arasındaki yerel olmayan değişkenler. olmayanlara kapsamlı erişim
yerliler güvenilirliği azaltabilir. Alt program tarafından görülebilen değişkenler
erişim isteniyorsa, genellikle erişimin olmadığı yerlerde de görünür hale gelir.
gerekli. Bu sorun Bölüm 5'te tartışıldı.
Yöntemler ayrıca yerel olmayan referanslar aracılığıyla harici verilere de erişir.
ve parametreler, bir yöntemle işlenecek birincil veriler nesnedir
hangi yöntem aracılığıyla çağrılır. Ancak, bir yöntem erişim sağladığında
yerel olmayan veriler, güvenilirlik sorunları yöntem olmayan alt verilerle aynıdır.
programlar. Ayrıca, nesne yönelimli bir dilde, sınıf değişkenlerine yöntem erişimi
(bir nesneden ziyade sınıfla ilişkili olanlar) kavramla ilgilidir.
yerel olmayan verilerdir ve mümkün olduğunca kaçınılmalıdır. Bu durumda da
yerel olmayan verilere erişen bir C işlevinin durumunda olduğu gibi, yöntem aşağıdakilere sahip olabilir:
parametreleri veya yerel veriler dışında bir şeyi değiştirmenin yan etkisi. Çok
değişiklikler yöntemin anlamını karmaşıklaştırır ve daha az güvenilir hale getirir.
Haskell gibi saf işlevsel programlama dillerinde
değiştirilebilir veriler, bu nedenle içlerinde yazılan işlevler hafızayı değiştiremez
herhangi bir şekilde—sadece hesaplamalar yaparlar ve sonuç değerini döndürürler (veya
işlev, çünkü işlevler değerlerdir).
Bazı durumlarda, hesaplamaları iletebilmek uygundur,
alt programlara parametre olarak veri yerine. Bu durumlarda, adı
bu hesaplamayı uygulayan alt program bir parametre olarak kullanılabilir.
eter. Bu parametre formu Bölüm 9.6'da tartışılmaktadır. Veri parametreleri
Bölüm 9.5'te tartışılmıştır.
Alt program başlığındaki parametrelere biçimsel parametreler denir .
Değişken olmadıkları için bazen kukla değişkenler olarak düşünülürler.
genel anlamda: Çoğu durumda, yalnızca alt program olduğunda depolamaya bağlıdırlar.
gram denir ve bu bağlama genellikle diğer bazı program değişkenleri aracılığıyla yapılır.

Sayfa 413
392
Bölüm 9 Alt Programlar
Alt program çağrı ifadeleri, alt programın adını ve
alt programın resmi parametrelerine bağlanacak bir parametre listesi.
Bu parametrelere gerçek parametreler denir . 2 Ayırt edilmelidirler
resmi parametrelerden, çünkü ikisi genellikle üzerinde farklı kısıtlamalara sahiptir.
biçimleri ve elbette kullanımları oldukça farklıdır.
Hemen hemen tüm programlama dillerinde, aralarındaki yazışmalar
gerçek ve biçimsel parametreler—veya gerçek parametrelerin biçimsel parametrelere bağlanması
parametreler—konuma göre yapılır: İlk gerçek parametre,
ilk resmi parametre vb. Bu tür parametrelere konumsal denir
parametreler . Bu, gerçek parametreleri ilişkilendirmenin etkili ve güvenli bir yöntemidir.
parametre listelendiği sürece, karşılık gelen resmi parametrelerine girer
nispeten kısadır.
Ancak listeler uzun olduğunda, bir programcının hata yapması kolaydır.
listedeki gerçek parametrelerin sırası. Bu soruna bir çözüm, pro-
vide kelime parametreleri , hangi biçimsel parametre adı hangi
bir çağrıdaki gerçek parametre ile bağlanacak gerçek bir parametre belirtilir.
Anahtar kelime parametrelerinin avantajı, anahtar kelime parametrelerinin herhangi bir sırada görünebilmeleridir.
gerçek parametre listesi. Python işlevleri, aşağıdaki gibi bu teknik kullanılarak çağrılabilir.
sumer(uzunluk = benim_uzunluk,
liste = benim_dizim,
toplam = my_sum)
tanımı nerede Sümer vardır biçimsel parametreler uzunluğu , liste ve
toplamı .
Anahtar kelime parametrelerinin dezavantajı, alt programın kullanıcısının
gram resmi parametrelerin adlarını bilmelidir.
Anahtar kelime parametrelerine ek olarak Ada, Fortran 95+ ve Python,
ulusal parametreler. Anahtar sözcük ve konum parametreleri, aşağıdaki gibi bir aramada karıştırılabilir:
sümer(uzunluğum,
toplam = my_sum,
liste = dizim)
Bu yaklaşımla ilgili tek kısıtlama, bir anahtar kelime parametresinden sonra
listede göründüğünde, kalan tüm parametreler anahtar kelime olarak belirtilmelidir. Bu kısıtla-
bir pozisyon artık bir anahtardan sonra iyi tanımlanamayabilir çünkü gereklidir.
word parametresi çıktı.
Python, Ruby, C++, Fortran 95+ Ada ve PHP'de resmi parametreler,
varsayılan değerlere sahiptir. Gerçek bir parametre iletilmezse varsayılan bir değer kullanılır
alt program başlığındaki resmi parametreye. Aşağıdakileri göz önünde bulundur
Python işlev başlığı:
def hesaplama_pay(gelir, muafiyetler = 1, vergi oranı)
2. Bazı yazarlar gerçek parametreleri argümanlar ve resmi parametreleri sadece parametreler olarak adlandırır .

Sayfa 414
9.2 Alt Programların Temelleri 393
Muafiyetler biçimsel parametre bir çağrı eksik olabilir compute_pay ;
olduğunda, 1 değeri kullanılır. Eksik gerçek için virgül eklenmez
bir Python çağrısında parametre, çünkü böyle bir virgülün tek değeri
bu durumda gerekli olmayan bir sonraki parametrenin konumunu belirtmek için
sary çünkü mevcut olmayan bir gerçek parametreden sonraki tüm gerçek parametreler
anahtar kelime. Örneğin, aşağıdaki çağrıyı düşünün:
ödeme = hesaplama_pay(20000.0, vergi_oranı = 0.15)
Anahtar kelime parametrelerini desteklemeyen C++'da varsayılan için kurallar
parametreler mutlaka farklıdır. Varsayılan parametreler en son görünmelidir,
çünkü parametreler konumsal olarak ilişkilidir. Varsayılan bir parametre olduğunda
bir çağrıda atlanırsa, kalan tüm resmi parametreler varsayılan değerlere sahip olmalıdır.
Compute_pay işlevi için bir C++ işlev başlığı şu şekilde yazılabilir:
şöyle:
şamandıra compute_pay ( şamandıra gelir, şamandıra TAX_RATE,
int muafiyetleri = 1)
Parametrelerin, varsayılan değere sahip olacak şekilde yeniden düzenlendiğine dikkat edin.
son. C++ hesaplama_pay işlevine örnek bir çağrı :
ödeme = hesaplama_pay(20000.0, 0.15);
Resmi parametreler için varsayılan değerlere sahip olmayan çoğu dilde,
bir çağrıdaki gerçek parametre sayısı, resmi parametre sayısıyla eşleşmelidir.
alt program tanım başlığındaki parametreler. Ancak, C, C++, Perl'de,
JavaScript ve Lua bu gerekli değildir. Daha az gerçek parametre olduğunda
bir işlev tanımındaki biçimsel parametrelerden daha fazla bir çağrıya girer, bu programdır.
mer'in sorumluluğunda olan parametre yazışmalarını sağlamak
her zaman konumsaldır ve alt program yürütmesi mantıklıdır.
Değişken sayıda parametreye izin veren bu tasarım,
hataya açık bir şekilde eğilimlidir, aynı zamanda bazen uygundur. Örneğin, printf
C'nin işlevi herhangi bir sayıda öğeyi (veri değerleri ve/veya değişmez değerler) yazdırabilir.
C#, yöntemlerin değişken sayıda parametreyi kabul etmesine izin verir.
onlar aynı türden. Yöntem, resmi parametresini şu şekilde belirtir:
param değiştirici. Çağrı, bir dizi veya ifade listesi gönderebilir,
değerleri derleyici tarafından bir diziye yerleştirilen ve aranan kişiye sağlanan
yöntem. Örneğin, aşağıdaki yöntemi göz önünde bulundurun:
public void DisplayList( params int [] list) {
foreach ( int aşağıdaki olarak listesi) {
Console.WriteLine("Sonraki değer {0}", sonraki);
}
}

Sayfa 415
394
Bölüm 9 Alt Programlar
Eğer displayList sınıfı için tanımlanan Sınıfım ve takipçileriniz var
beyannameler,
Sınıfım myObject = yeni Sınıfım;
int [] myList = yeni int [6] {2, 4, 6, 8, 10, 12};
DisplayList aşağıdakilerden biri ile çağrılabilir:
myObject.DisplayList(myList);
myObject.DisplayList(2, 4, 3 * x - 1, 17);
Ruby, karmaşık ancak oldukça esnek bir gerçek parametre yapılandırmasını destekler.
tion. İlk parametreler, değer nesneleri iletilen ifadelerdir.
karşılık gelen resmi parametreler. İlk parametreler bir liste ile takip edilebilir
anahtar => değer çiftleri, anonim bir karmaya yerleştirilen ve bir referansa
bu karma bir sonraki resmi parametreye iletilir. Bunlar yerine kullanılır
Ruby'nin desteklemediği anahtar kelime parametreleri. Hash öğesi takip edilebilir
önünde bir yıldız işareti bulunan tek bir parametre ile. Bu parametreye dizi denir
biçimsel parametre . Yöntem çağrıldığında, dizi biçimsel parametresi olarak ayarlanır.
yeni bir Array nesnesine başvurun . Kalan tüm gerçek parametreler,
yeni Array nesnesinin öğeleri . Buna karşılık gelen gerçek parametre
dizi biçimsel parametresi bir dizidir, önünde bir yıldız işareti de bulunmalıdır ve
son gerçek parametre olmalıdır. 3 Yani, Ruby değişken sayıda parametreye izin verir
C#'a benzer bir şekilde. Ruby dizileri farklı türleri depolayabildiğinden,
diziye iletilen gerçek parametrelerin aynı türde olması gerekli değildir.
Aşağıdaki örnek iskelet işlevi tanımı ve çağrısı,
Ruby'nin parametre yapısı:
liste = [2, 4, 6, 8]
def test cihazı(p1, p2, p3, *p4)
. . .
son
. . .
tester('first', pzt => 72, sal => 68, çar => 59, *liste)
İçinde test aşağıdaki gibi onun biçimsel parametre değerleri şunlardır:
p1 'ilk'
p2 {mon => 72, sal => 68, çar => 59}
p3 2'dir
p4, [4, 6, 8]
Python, Ruby'ninkine benzer parametreleri destekler.
3. Tam olarak doğru değil, çünkü dizi biçimsel parametresinin ardından bir yöntem veya işlev gelebilir
önünde bir ve işareti (&) bulunan başvuru.

Sayfa 416
9.2 Alt Programların Temelleri 395
Lua, değişken sayıda parametreyi desteklemek için basit bir mekanizma kullanır.
eterler—bu tür parametreler bir üç nokta ( . . . . ) ile temsil edilir . Bu elips olabilir
bir dizi veya bir değişkenler listesine atanabilecek bir değerler listesi olarak ele alınır.
Örneğin, aşağıdaki iki işlev örneğini göz önünde bulundurun:
fonksiyon çarpma (. . .)
yerel ürün = 1
için i, bir sonraki içinde {ipairs. . .} yapmak
ürün = ürün * sonraki
son
dönüş toplamı
son
ipairs diziler için bir yineleyicidir (elemanların indeksini ve değerini döndürür
bir dizi, her seferinde bir eleman). {. . .} gerçek parametrenin bir dizisidir
değerler.
işlev DoIt (. . .)
yerel a, b, c = . . .
. . .
son
DoIt'in aşağıdaki çağrıyla çağrıldığını varsayalım :
nokta(4, 7, 3)
Bu örnekte, a , b ve c , fonksiyonda 4 değerlerine başlatılacaktır ,
sırasıyla 7 ve 3 .
Üç dönemli parametrenin tek parametre olması gerekmez;
adlandırılmış resmi parametreler listesinin sonunda.
9.2.4 Prosedürler ve Fonksiyonlar
İki farklı alt program kategorisi vardır - prosedürler ve işlevler -
her ikisi de dili genişletmeye yönelik yaklaşımlar olarak görülebilir. Tüm alt
programlar, parametreli hesaplamaları tanımlayan ifadelerin koleksiyonlarıdır.
İşlevler değerleri döndürür ve prosedürler döndürmez. olmayan çoğu dilde
prosedürleri ayrı bir alt program biçimi olarak içerir, fonksiyonlar tanımlanamaz
değerleri döndürmek için ve prosedürler olarak kullanılabilirler. Bir işlemin hesaplamaları
dure, tek çağrı ifadeleriyle yürürlüğe girer. Aslında, prosedürler yeni durumu tanımlar.
mentler. Örneğin, belirli bir dilde bir sıralama ifadesi yoksa, bir kullanıcı
veri dizilerini sıralamak için bir prosedür oluşturabilir ve bu prosedüre bir çağrıyı yerinde kullanabilir
kullanılamayan sıralama ifadesinin. Ada'da prosedürler tam olarak şöyle adlandırılır; Fortran'da,
bunlara alt programlar denir. Diğer dillerin çoğu yordamları desteklemez.
Prosedürler, çağıran program biriminde iki yöntemle sonuçlar üretebilir.
ods: (1) Resmi parametre olmayan ancak yine de görünür olan değişkenler varsa

Sayfa 417
396
Bölüm 9 Alt Programlar
hem prosedürde hem de çağıran program biriminde prosedür değişebilir
onlara; ve (2) prosedürün transferine izin veren resmi parametrelere sahip olması durumunda
arayana veri, bu parametreler değiştirilebilir.
Fonksiyonlar yapısal olarak prosedürlere benzer ancak anlamsal olarak modellenmiştir.
matematiksel fonksiyonlar üzerine Bir fonksiyon sadık bir model ise, hiçbir
yan etkiler; yani, ne parametrelerini ne de tanımlanan herhangi bir değişkeni değiştirmez.
fonksiyonun dışında. Böyle saf bir işlev bir değer döndürür - bu onun tek işlevidir.
istenen etki. Pratikte, çoğu programlama dilindeki fonksiyonlar
yan etkiler.
İşlevler, adlarının ifadelerdeki görünümleriyle çağrılır.
gerekli gerçek parametrelerle. Bir işlevin yürütmesi tarafından üretilen değer
arama koduna döndürülür ve aramanın kendisinin yerini alır. İçin
örneğin, f(x) ifadesinin değeri, f'nin ürettiği değer ne olursa olsun ,
x parametresi ile çağrılır . Yan etki oluşturmayan bir fonksiyon için,
döndürülen değer onun tek etkisidir.
Fonksiyonlar, yeni kullanıcı tanımlı operatörleri tanımlar. Örneğin, eğer bir dil
üs alma operatörü yoksa, dönen bir fonksiyon yazılabilir.
parametrelerinden birinin değeri, başka bir parametrenin gücüne yükseltilmiştir. Onun
C++'da başlık olabilir
şamandıra gücü ( şamandıra tabanı, şamandıra exp)
hangi ile çağrılabilir
sonuç = 3.4 * güç (10.0, x)
Standart C++ kitaplığı zaten pow adlı benzer bir işlevi içerir . iletişim
bunu, üs almanın yerleşik olduğu Perl'deki aynı işlemle karşılaştırın
operasyon:
sonuç = 3.4 * 10.0 ** x
Bazı programlama dillerinde, kullanıcıların operatörleri aşırı yüklemesine izin verilir.
operatörler için yeni fonksiyonlar tanımlayarak. Kullanıcı tanımlı aşırı yüklenmiş operatörler
Bölüm 9.11'de tartışılmıştır.
9.3 Alt Programlar için Tasarım Konuları
Alt programlar, programlama dillerindeki karmaşık yapılardır ve aşağıdaki şekildedir:
bundan, tasarımlarında uzun bir sorun listesi yer almaktadır. bir bariz
sorun, kullanılacak bir veya daha fazla parametre geçirme yönteminin seçimidir.
Çeşitli dillerde kullanılan çok çeşitli yaklaşımlar,
konudaki görüş çeşitliliğinin yansımasıdır. yakından ilgili bir konu
gerçek parametre türlerinin tiplere karşı tip kontrolü yapılıp yapılmayacağı
karşılık gelen resmi parametreler.

Sayfa 418
9.4 Yerel Referans Ortamları 397
Bir alt programın yerel ortamının doğası, bazı
alt programın doğasını derecelendirir. Buradaki en önemli soru
yerel değişkenlerin statik veya dinamik olarak tahsis edilip edilmediği.
Daha sonra, alt program tanımlarının yapılıp yapılamayacağı sorusu vardır.
yuvalanmış. Diğer bir konu da alt program adlarının parametre olarak geçirilip geçirilemeyeceğidir.
eter. Alt program adları parametre olarak geçirilebiliyorsa ve dil izin veriyorsa
alt programlar iç içe olacaksa, doğru referanslama sorunu var
parametre olarak geçirilen bir alt programın ortamı.
Son olarak, alt programların aşırı yüklenip yüklenemeyeceği soruları vardır.
veya jenerik. Aşırı yüklenmiş bir alt program , aşağıdakilerle aynı ada sahip olandır .
aynı referans ortamında başka bir alt program. Bir jenerik subpro-
gram , farklı türlerdeki veriler üzerinde farklı şekillerde hesaplanabilen bir
ateşli aramalar Bir kapak iç içe bir alt program ve referans ortamıdır,
bunlar birlikte alt programın bir programdaki herhangi bir yerden çağrılmasına izin verir.
Aşağıdakiler, aşağıdaki alt programlar için bu tasarım konularının bir özetidir:
Genel. Özellikle işlevlerle ilişkilendirilen ek sorunlar şunlardır:
Bölüm 9.10'da tartışılmıştır.
• Yerel değişkenler statik veya dinamik olarak tahsis edilmiş mi?
• Alt program tanımları diğer alt program tanımlarında görünebilir mi?
• Hangi parametre geçirme yöntemi veya yöntemleri kullanılıyor?
• Gerçek parametre türleri, gerçek parametrelerin türlerine göre kontrol ediliyor mu?
biçimsel parametreler?
• Alt programlar parametre olarak geçirilebiliyorsa ve alt programlar iç içe geçebiliyorsa,
geçirilen bir alt programın referans ortamı nedir?
• Alt programlar aşırı yüklenebilir mi?
• Alt programlar genel olabilir mi?
• Dil iç içe alt programlara izin veriyorsa, kapatmalar destekleniyor mu?
Bu konular ve örnek tasarımlar aşağıdaki bölümlerde tartışılmaktadır.
9.4 Yerel Referans Ortamları
Bu bölüm, alt bölümlerde tanımlanan değişkenlerle ilgili konuları tartışır.
programlar. İç içe alt program tanımları konusu da kısaca ele alınmıştır.
9.4.1 Yerel Değişkenler
Alt programlar kendi değişkenlerini tanımlayabilir, böylece yerel referansları tanımlayabilir
ortamlar. Alt programlar içinde tanımlanan değişkenlere yerel denir.
değişkenler , çünkü kapsamları genellikle içinde bulunduğu alt programın gövdesidir.
tanımlanırlar.
Bölüm 5'in terminolojisinde yerel değişkenler ya statik ya da
yığın dinamik. Yerel değişkenler yığın dinamik ise, depolamaya bağlıdırlar.

Sayfa 419
398
Bölüm 9 Alt Programlar
alt program yürütmeye başladığında ve depolamadan ayrıldığında
bu yürütme sona erer. Yığın dinamik yerelin birçok avantajı vardır.
değişkenler, birincil olanı alt programa sağladıkları esnekliktir.
Özyinelemeli alt programların yığın dinamik yerel değişkenlere sahip olması önemlidir.
Yığın dinamik yerellerin bir başka avantajı, yerel değişkenler için depolamanın olmasıdır.
aktif bir alt programdaki tüm aktif olmayan yerel değişkenler ile paylaşılabilir.
alt programlar. Bu, bilgisayarların olduğu zamanki kadar büyük bir avantaj değil.
daha küçük hatıralar
Yığın dinamik yerel değişkenlerin ana dezavantajları şunlardır:
İlk olarak, tahsis etmek, başlatmak (gerektiğinde) için gereken zamanın maliyeti vardır.
sary) ve alt programa yapılan her çağrı için bu tür değişkenleri serbest bırakın. İkinci,
yığın dinamik yerel değişkenlere erişimler dolaylı olmalıdır, oysa
statik değişkenler doğrudan olabilir. 4 Bu dolaylılık gereklidir çünkü yer
belirli bir yerel değişkenin bulunacağı yığında yalnızca belirlenebilir
yürütme sırasında (bkz. Bölüm 10). Son olarak, tüm yerel değişkenler yığın olduğunda
dinamik, alt programlar geçmişe duyarlı olamaz; yani tutamazlar
çağrılar arasındaki yerel değişkenlerin veri değerleri. Bazen uygun olmak
tarihe duyarlı alt programlar yazabilir. yaygın bir ihtiyaç örneği
tarihe duyarlı bir alt program, görevi sözde rasgele oluşturmak olan bir alt programdır.
sayılar. Böyle bir alt programa yapılan her çağrı, bir sözde rasgele sayı hesaplar.
ber, hesapladığı sonuncuyu kullanarak. Bu nedenle, sonuncuyu bir
statik yerel değişken. Yineleyici döngüsünde kullanılan eşyordamlar ve alt programlar
yapılar (Bölüm 8'de tartışılmıştır) diğer alt program örnekleridir.
tarihe duyarlı olmak gerekir.
Statik yerel değişkenlerin yığın dinamik yerel değişkenlere göre birincil avantajı
değişkenler biraz daha verimli olmalarıdır—fazla çalışma süresi gerektirmezler.
tahsis ve tahsis için kafa. Ayrıca, doğrudan erişilirse, bu erişimler
açıkçası daha verimli. Ve elbette, alt programların tarih olmasına izin veriyorlar.
duyarlı. Statik yerel değişkenlerin en büyük dezavantajı,
özyinelemeyi destekler. Ayrıca, depoları yerel değişkenlerle paylaşılamaz.
diğer etkin olmayan alt programların
Çoğu çağdaş dilde, bir alt programdaki yerel değişkenler
varsayılan yığın dinamik. C ve C++ işlevlerinde yereller,
özellikle statik olduğu bildirildi . Örneğin, aşağıdaki C'de (veya C++)
işlevinde, toplam değişkeni statiktir ve sayım yığın dinamiktir.
int toplayıcı( int liste[], int listelen) {
statik int toplam = 0;
int sayısı;
for (sayım = 0; sayım < listelen; sayım ++)
toplam += liste [sayım];
dönüş toplamı;
}
4. Bazı uygulamalarda, statik değişkenlere dolaylı olarak da erişilir, böylece ortadan kalkar.
bu dezavantaj.

Sayfa 420
9.5 Parametre Geçiş Yöntemleri 399
C++, Java ve C# yöntemlerinde yalnızca yığın dinamik yerel değişkenler bulunur.
Python'da, yöntem tanımlarında kullanılan bildirimler yalnızca
küreseller. Bir yöntemde global olduğu bildirilen herhangi bir değişken, bir değişken olmalıdır
yöntemin dışında tanımlanmıştır. Yöntemin dışında tanımlanan bir değişken,
yöntemde global olduğu bildirilmeden atıfta bulunulur, ancak böyle bir değişken
yönteminde atanamaz. Global bir değişkenin adı ise
bir yöntemde atanırsa, dolaylı olarak yerel olduğu bildirilir ve atama-
küreseli rahatsız etmiyor. Python yöntemlerindeki tüm yerel değişkenler
yığın dinamik.
Lua'da yalnızca sınırlı kapsamı olan değişkenler bildirilir. Herhangi bir blok, dahil-
Bir fonksiyonun gövdesini ing, yerel değişkenleri ilan edebilir yerel Beyannameler-
aşağıdaki gibidir:
yerel toplam
Lua'daki tüm bildirilmemiş değişkenler globaldir. Yerel değişkenlere erişim
Lua'da Ierusalimschy'ye göre küresel değişkenlere erişimden daha hızlıdır
(2006).
9.4.2 İç İçe Alt Programlar
Alt programları yerleştirme fikri Algol 60 ile ortaya çıktı.
hem mantık hem de kapsam hiyerarşisi oluşturabilmek. Bir alt program ise
sadece başka bir alt program içinde gerekliyse, neden oraya yerleştirip ondan gizlemiyorsunuz?
programın geri kalanı? Statik kapsam genellikle dillerde kullanıldığı için
alt programların iç içe geçmesine izin verir, bu aynı zamanda oldukça yapılandırılmış bir yol sağlar
çevreleyen alt programlarda yerel olmayan değişkenlere erişim izni vermek. Bunu hatırla
Bölüm 5, bunun getirdiği sorunlar tartışıldı. Uzun bir süre,
yalnızca iç içe alt programlara izin veren diller, doğrudan azalan dillerdi.
Algol 68, Pascal ve Ada olan Algol 60'tan. Diğer birçok dil,
C'nin tüm doğrudan torunları dahil olmak üzere, alt program yuvalarına izin vermeyin.
ing. Son zamanlarda, bazı yeni diller buna tekrar izin veriyor. Bunlar arasında JavaScript,
Python, Ruby ve Lua. Ayrıca, çoğu işlevsel programlama dili,
alt programlar iç içe.
9.5 Parametre Geçiş Yöntemi s
Parametre geçirme yöntemleri, parametrelerin iletilme biçimleridir.
çağrılan alt programlara ve/veya bunlardan. İlk olarak, farklı anlambilime odaklanıyoruz
parametre geçirme yöntemlerinin modelleri. Daha sonra, çeşitli uygulamaları tartışırız.
bu semantik modlar için dil tasarımcıları tarafından icat edilen düşünme modelleri
el. Daha sonra, çeşitli dillerin tasarım seçimlerini inceleyeceğiz ve
uygulama modellerini uygulamak için kullanılan gerçek yöntemler. Sonunda biz

Sayfa 421
400
Bölüm 9 Alt Programlar
seçim yaparken bir dil tasarımcısının karşılaştığı tasarım hususlarını göz önünde bulundurun
yöntemler arasındadır.
9.5.1 Parametre Geçişinin Semantik Modelleri
Resmi parametreler, üç farklı semantik modelden biri ile karakterize edilir:
(1) İlgili gerçek parametreden veri alabilirler; (2) yapabilirler
verileri gerçek parametreye iletin; veya (3) her ikisini de yapabilirler. Bu modeller
denilen modda , dışarı modunda ve inout mode sırasıyla. Örneğin, düşünün
parametre olarak iki dizi int değeri alan bir alt program— list1 ve
liste2 . Alt program eklemelisiniz list1 için list2 ve a olarak sonuç döndürmek
list2'nin gözden geçirilmiş versiyonu . Ayrıca, alt program yeni bir dizi oluşturmalıdır.
verilen iki diziden ve döndürün. Bu alt program için liste1 olmalıdır
modundadır, çünkü alt program tarafından değiştirilemez. liste2 olmalı
giriş modu, çünkü alt program dizinin verilen değerine ihtiyaç duyar ve
yeni değerini döndürür. Üçüncü dizi, dışarıda mod olmalıdır, çünkü
bu dizinin başlangıç ​​değeri ve hesaplanan değeri arayana döndürülmelidir.
Veri aktarımlarının nasıl gerçekleştiğine dair iki kavramsal model vardır.
parametre aktarımı: Ya gerçek bir değer kopyalanır (arayana,
çağrılır veya her iki şekilde) veya bir erişim yolu iletilir. En yaygın olarak,
erişim yolu basit bir işaretçi veya referanstır. Şekil 9.1, üç
değerler kopyalandığında geçen parametrenin anlamsal modelleri.
9.5.2 Parametre Geçişi Uygulama Modelleri
Uygulamaya rehberlik etmek için dil tasarımcıları tarafından çeşitli modeller geliştirilmiştir.
üç temel parametre iletim modunun belirtilmesi. Aşağıdaki bölümde-
göreli güçlü ve zayıf yönleriyle birlikte bunlardan birkaçını tartışıyoruz.
Şekil 9.1
üç semantik
parametre modelleri
fiziksel olduğunda geçmek
hareketler kullanılır
a
x
Telefon etmek
B
y
Dönüş
Dönüş
C
z
Telefon etmek
arayan
(alt (a, b, c))
Callee
( geçersiz alt ( int x, int y, int z))
modunda
Çıkış modu
giriş modu

Sayfa 422
9.5 Parametre Geçiş Yöntemleri
401
9.5.2.1 Geçiş Değeri
Bir parametre değer tarafından iletildiğinde , gerçek parametrenin değeri kullanılır.
karşılık gelen resmi parametreyi başlatmak, bu daha sonra yerel olarak işlev görür.
alt programdaki değişken, böylece mod içi anlambilimi uygular.
Değere göre geçiş normalde kopya ile uygulanır, çünkü erişimler genellikle
Bu yaklaşımla daha verimli. İletilerek uygulanabilir.
arayandaki gerçek parametrenin değerine erişim yolu, ancak bu
değerin yazmaya karşı korumalı (yalnızca okunabilen) bir hücrede olmasını gerektirir.
Yazma korumasını zorlamak her zaman basit bir mesele değildir. Örneğin,
parametrenin geçirildiği alt programın sırayla onu geçtiğini varsayalım
başka bir alt programa Bu, kopya aktarımını kullanmanın başka bir nedenidir. biz olarak
Bölüm 9.5.4'te göreceğimiz gibi, C++ aşağıdakiler için uygun ve etkili bir yöntem sağlar:
iletilen değere göre geçiş parametrelerinde yazma korumasının belirtilmesi
erişim yolu ile.
Değere göre geçişin avantajı, skalerler için hızlı olmasıdır, her iki bağlantıda da
maliyet ve erişim süresi.
Kopyalar kullanılıyorsa, değere göre geçiş yönteminin ana dezavantajı
resmi parametre için ek depolamanın gerekli olmasıdır.
olarak adlandırılan alt program veya hem arayan hem de aranan alt program dışındaki bir alanda
programı. Ek olarak, gerçek parametre depolama alanına kopyalanmalıdır.
karşılık gelen resmi parametre için. Depolama ve kopyalama işlemleri
parametre büyükse, örneğin birçok öğeye sahip bir dizide olduğu gibi maliyetli olabilir.
9.5.2.2 Sonuca Göre Geçiş
Sonuç olarak geçiş , mod dışı parametreler için bir uygulama modelidir. Ne zaman
sonuca göre bir parametre iletilir, alt programa hiçbir değer iletilmez. bu
karşılık gelen biçimsel parametre yerel bir değişken gibi davranır, ancak kontrolden hemen önce
arayan kişiye geri aktarılır, değeri arayanın gerçek değerine geri iletilir.
açıkça bir değişken olması gereken parametre. (Arayan nasıl başvurur
hesaplanan sonuç bir hazır bilgi mi yoksa bir ifade mi?)
Sonuç-by-sonuç yöntemi, geçiş yönteminin avantaj ve dezavantajlarına sahiptir.
değer, artı bazı ek dezavantajlar. Değerler kopya ile döndürülürse (
erişim yollarının aksine), tipik olarak olduğu gibi, sonuca göre geçiş ayrıca şunları gerektirir:
ekstra depolama ve geçiş değeri tarafından gerekli olan kopyalama işlemleri. Olarak
geçiş değeri ile, iletme yoluyla geçiş sonucu uygulamanın zorluğu
bir erişim yolunun oluşturulması, genellikle bunun kopyalanarak uygulanmasıyla sonuçlanır. Bu durumda,
sorun, gerçek parametrenin başlangıç ​​değerinin olmamasını sağlamaktır.
çağrılan alt programda kullanılır.
Sonuç-by-sonuç modeliyle ilgili ek bir sorun,
çağrı ile oluşturulan gibi gerçek bir parametre çakışması
alt(p1, p1)
In alt varsayarsak iki resmi parametreleri, iki kutu farklı adlara sahip
açıkça farklı değerler atanır. Ardından, ikisinden hangisi kopyalanırsa

Sayfa 423
402
Bölüm 9 Alt Programlar
karşılık gelen gerçek parametresi, arayandaki p1 değeri olur .
Böylece, gerçek parametrelerin kopyalanma sırası, onların gerçek parametrelerini belirler.
değer. Örneğin, aşağıdaki C# yöntemini göz önünde bulundurun:
biçimsel parametresinde çıkış belirteciyle sonuç-by-sonuç yöntemi . 5
void Fixer( out int x, out int y) {
x = 17;
y = 35;
}
. . .
f.Fixer( dışarı a, dışarı a);
Fixer uygulamasının sonunda, x resmi parametresi atanmışsa
önce karşılık gelen gerçek parametresi, ardından gerçek parametrenin değeri
a arayan kişi 35 olacaktır . Eğer Y , ilk asıl sonra değeri atanır
arayandaki a parametresi 17 olacaktır .
Sıralama bazı diller için uygulamaya bağlı olabileceğinden,
farklı uygulamalar farklı sonuçlar doğurabilir.
Aynı iki gerçek parametreye sahip bir prosedürün çağrılması da
diğer parametre geçirme yöntemleri kullanıldığında farklı türde problemler,
Bölüm 9.5.2.4'te tartışıldığı gibi.
Geçiş sonucu ile ortaya çıkabilecek bir diğer sorun, uygulamanın
tor, adresleri değerlendirmek için iki farklı zaman arasında seçim yapabilir.
gerçek parametrelerin sayısı: arama sırasında veya geri dönüş sırasında. İçin
örneğin, aşağıdaki C# yöntemini ve aşağıdaki kodu göz önünde bulundurun:
void DoIt( out int x, int index){
x = 17;
indeks = 42;
}
. . .
alt = 21;
f.DoIt(liste[alt], alt);
list[sub] adresinin başlangıcı ve bitişi arasında değişir.
yöntem. Uygulayıcı, bu parametreyi bir
adres—çağrı sırasında veya geri dönüş sırasında. adres ise
yönteme girişte hesaplanan 17 değeri list[21]'e döndürülecektir ;
dönüşten hemen önce hesaplanırsa, 17 [42] listesine döndürülür . Bu yapar
değerlendirmeyi seçen bir uygulama arasında taşınabilir olmayan programlar
bir alt programın başlangıcındaki çıkış modu parametreleri için adresler ve bir
sonunda bu değerlendirmeyi yapmayı seçen kişi. Bunu önlemenin bariz bir yolu
sorun, dil tasarımcısının adresin ne zaman kullanılacağını belirlemesidir.
dönüş parametre değeri hesaplanmalıdır.
5. üzerinden belirteci ayrıca karşılık gelen gerçek parametre belirtilmelidir.

Sayfa 424
9.5 Parametre Geçiş Yöntemleri
403
9.5.2.3 Değerden Geçer-Sonuç
Geçiş - by - değeri - sonuç inout modu parametreleri için bir uygulama modelidir
gerçek değerlerin kopyalandığı. Aslında, değere göre geçişin bir kombinasyonudur.
ve geçiş sonucu. Gerçek parametrenin değeri, başlatmak için kullanılır.
daha sonra yerel bir değişken olarak hareket eden karşılık gelen resmi parametre. Aslında,
değer-sonuç-geçen biçimsel parametreler ile ilişkili yerel depolamaya sahip olmalıdır
denilen alt program. Alt program sonlandırıldığında, resmi programın değeri
parametre gerçek parametreye geri iletilir.
Değere göre-sonuç bazen kopyaya-geçen olarak adlandırılır , çünkü gerçek
parametre, alt program girişindeki resmi parametreye kopyalanır ve ardından
alt program sonlandırıldığında geri kopyalanır.
Değere göre geçiş sonucu paylaşımları, değere göre geçiş ve sonuca göre sonuç paylaşımları
parametreler için çoklu depolama ve kopyalama için zaman gerektirmenin avantajları
değerler. Siparişle ilgili sorunları doğrudan sonuca göre paylaşır.
hangi gerçek parametreler atanır.
Değere göre geçiş sonucunun avantajları, referansa göre geçişe göredir,
bu nedenle Bölüm 9.5.2.4'te tartışılmaktadır.
9.5.2.4 Referanstan Geçiş
Geçiş - ile - referans inout modu ParamChannel için ikinci bir uygulama modeli
eter. Bununla birlikte, geçişte olduğu gibi veri değerlerini ileri geri kopyalamak yerine
değer-sonuç, referanstan geçiş yöntemi bir erişim yolu iletir, genellikle sadece
aranan alt programa bir adres. Bu, hücreye erişim yolunu sağlar.
gerçek parametrenin kaydedilmesi. Böylece, çağrılan alt programın erişmesine izin verilir.
çağıran program birimindeki gerçek parametre. Aslında, gerçek parametre
çağrılan alt program ile paylaşılır.
Referanstan geçişin avantajı, geçiş sürecinin kendisinin
hem zaman hem de mekan açısından verimli. Yinelenen alan gerekli değildir veya
herhangi bir kopyalama gerekli mi.
Bununla birlikte, referanstan geçiş yönteminin birkaç dezavantajı vardır.
İlk olarak, resmi parametrelere erişim, değere göre geçiş parametrelerine göre daha yavaş olacaktır.
gerekli olan ek dolaylı adresleme düzeyi nedeniyle. 6
İkincisi, çağrılan alt programa yalnızca tek yönlü iletişim gerekiyorsa,
asıl parametrede yanlışlıkla ve hatalı değişiklikler yapılabilir.
Başka bir referans sorunu, takma adların oluşturulabilmesidir. Bu
sorun beklenmelidir, çünkü referansa göre geçiş, erişim yollarını kullanılabilir hale getirir.
çağrılan alt programlara erişebilir, böylece yerel olmayan değişkenlere erişim sağlar.
Bu tür takma adlarla ilgili sorun, diğer durumlardakiyle aynıdır:
Okunabilirliğe ve dolayısıyla güvenilirliğe zararlıdır. Ayrıca program doğrulamasını da yapar.
daha zor.
Referanstan geçiş parametrelerinin takma adlar oluşturmasının birkaç yolu vardır. Öncelikle,
gerçek parametreler arasında çarpışmalar meydana gelebilir. Bir C++ işlevi düşünün
referans olarak iletilecek iki parametreye sahiptir (bkz. Bölüm 9.5.3), aşağıdaki gibi
6. Bu, Bölüm 9.5.3'te daha ayrıntılı olarak açıklanmıştır.

Sayfa 425
404
Bölüm 9 Alt Programlar
void fun( int &birinci, int &ikinci)
Eğlence çağrısı , aşağıdaki gibi aynı değişkeni iki kez geçirirse
eğlence(toplam, toplam)
Daha sonra birinci ve ikinci yılında eğlenceli takma adları olacaktır.
İkincisi, dizi öğeleri arasındaki çarpışmalar da takma adlara neden olabilir. Sınav için-
ple, fun işlevinin belirli iki dizi öğesiyle çağrıldığını varsayalım.
olduğu gibi, değişken abonelikler ile fieded
eğlence(liste[i], liste[j])
Bu iki parametre referans olarak iletilirse ve i eşittir
j , sonra birinci ve ikinci yine takma adlardır.
Üçüncüsü, eğer bir alt programın resmi parametrelerinden ikisi bir
dizi ve tüm dizi ve her ikisi de başvuruya göre iletilir, ardından aşağıdaki gibi bir çağrı
fun1(liste[i], liste)
içinde aliasing neden olabilir FUN1 çünkü fun1 tüm unsurları erişebilir listede
ikinci parametre aracılığıyla ve birincisi aracılığıyla tek bir öğeye erişin
parametre.
Referansa göre parametrelerle takma ad almanın başka bir yolu da
biçimsel parametreler ve yerel olmayan değişkenler arasındaki çarpışmalar yoluyla
görünür. Örneğin, aşağıdaki C kodunu göz önünde bulundurun:
int * küresel;
geçersiz ana() {
. . .
alt(küresel);
. . .
}
void sub( int * param) {
. . .
}
İçinde sub , param ve global takma adlardır.
Tüm bu olası örtüşme durumları, değere göre geçiş sonucu elde edilirse ortadan kalkar.
referans yerine kullanılır. Ancak, takma ad yerine başka sorunlar
bazen Bölüm 9.5.2.3'te tartışıldığı gibi ortaya çıkar.
9.5.2.5 Adına Göre Geçiş
Pass - by - name , mod dışı bir parametre iletim yöntemidir.
tek bir uygulama modeline karşılık gelir. Parametreler iletildiğinde
adı, gerçek parametre, aslında, karşılık gelen için metinsel olarak ikame edilir.

Sayfa 426
9.5 Parametre Geçiş Yöntemleri
405
alt programdaki tüm oluşumlarında resmi parametre. Bu yöntem oldukça
şimdiye kadar tartışılanlardan farklı; bu durumda, biçimsel parametreler
alt program çağrısı sırasındaki gerçek değerlere veya adreslere bağlıdır. Bir geçiş-
name biçimsel parametresi, alt program sırasında bir erişim yöntemine bağlıdır.
gram çağrısı, ancak bir değere veya adrese gerçek bağlanma, resmi
parametre atanır veya başvurulur. Ada göre geçiş parametresi uygulama
değerlendirmek için çağrılan alt programa geçirilecek bir alt program gerektirir.
resmi parametrenin adresi veya değeri. Referans ortamı
geçilen alt program da geçilmelidir. Bu alt program/referanslama ortamı
ment bir kapatmadır (bkz. Bölüm 9.12). 7 Adına göre geçiş parametrelerinin her ikisi de karmaşıktır
uygulamak ve verimsiz. Ayrıca pro-
gram, dolayısıyla okunabilirliğini ve güvenilirliğini düşürür.
Adına göre geçiş, yaygın olarak kullanılan herhangi bir dilin parçası olmadığı için,
burada daha fazla tartışıldı. Ancak, derleme zamanında makrolar tarafından kullanılır.
derleme dilleri ve genel alt programların genel parametreleri için
Bölüm 9.9'da tartışıldığı gibi C++, Java 5.0 ve C# 2005'te.
9.5.3 Parametre Geçirme Yöntemlerinin Uygulanması
Şimdi, çeşitli uygulama modellerinin nasıl olduğu sorusunu ele alıyoruz.
parametre geçişi aslında uygulanmaktadır.
Çoğu çağdaş dilde, parametre iletişimi gerçekleşir
çalışma zamanı yığını aracılığıyla. Çalışma zamanı yığını başlatılır ve korunur
programların yürütülmesini yöneten çalışma zamanı sistemi tarafından. Koşmak-
zaman yığını, alt program kontrol bağlantısı ve parametre için yaygın olarak kullanılır
Bölüm 10'da tartışıldığı gibi geçiyoruz. Aşağıdaki tartışmada,
yığın tüm parametre iletimi için kullanılır.
Değere göre geçiş parametrelerinin değerleri yığın konumlarına kopyalanır.
Yığın konumları daha sonra karşılık gelen resmi parametreler için depolama görevi görür.
eter. Geçiş sonucu parametreleri, geçişin tersi olarak uygulanır.
değer. Sonuca göre gerçek parametrelere atanan değerler yerleştirilir
çağıran program birimi tarafından alınabilecekleri yığında
çağrılan alt programın sonlandırılması. Değere göre sonuç parametreleri şunlar olabilir:
değer geçişinin bir kombinasyonu olarak doğrudan anlambilimlerinden uygulanır
ve geçiş sonucu. Böyle bir parametre için yığın konumu,
çağrılır ve daha sonra çağrılan alt programda yerel bir değişken gibi kullanılır.
Referansa dayalı parametreler, uygulanması belki de en basit olanlardır.
Gerçek parametrenin türünden bağımsız olarak, yalnızca adresi yerleştirilmelidir.
yığında. Hazır bilgi durumunda, değişmezin adresi yığına konur. İçinde
bir ifade durumunda, derleyici ifadeyi değerlendirmek için kod oluşturmalıdır.
kontrolün çağrılan alt programa aktarılmasından hemen önce. adres
Kodun değerlendirme sonucunu yerleştirdiği bellek hücresinin
yığına koyun. Derleyici, çağrılan alt programı engellediğinden emin olmalıdır.
değişmezler veya ifadeler olan parametreleri değiştirmekten.
7. Bu kapaklar orijinal olarak (ALGOL 60'ta) thunks olarak adlandırılıyordu . Kapanışlar Bölümde tartışılıyor
9.12.

Sayfa 427
406
Bölüm 9 Alt Programlar
Çağrılan alt programdaki resmi parametrelere erişim dolaylı olarak yapılır.
adresin yığın konumundan adresleme. Geçişin uygulanması-
çalışma zamanı yığınının olduğu değere göre, -sonuç, -değer-sonuç ve -referans
kullanılan, Şekil 9.2'de gösterilmiştir. Alt program alt çağrılır ana ile
Çağrı alt (w, x, y, z) , ağırlık değeri ile geçirilir, X sonucu ile geçirilir, y olan
değer sonucu iletilir ve z başvuru ile iletilir.
9.5.4 Bazı Ortak Dillerin Parametre Geçirme Yöntemleri
C geçiş değeri kullanır. Referanstan geçiş (giriş modu) semantiği şu şekilde elde edilir:
işaretçileri parametre olarak kullanmak. İşaretçinin değeri,
işlev denir ve hiçbir şey geri kopyalanmaz. Ancak, çünkü ne geçti
arayanın verilerine erişim yoludur, aranan işlev aramayı değiştirebilir-
er verileri. C, değer iletme yönteminin bu kullanımını ALGOL 68'den kopyalamıştır.
hem C hem de C++, biçimsel parametreler sabitlere işaretçiler olarak yazılabilir. bu
karşılık gelen gerçek parametrelerin sabit olması gerekmez, çünkü bu gibi durumlarda
sabitlere zorlanır. Bu, işaretçi parametrelerinin verimliliği sağlamasına izin verir.
değerin tek yönlü semantiği ile referanstan geçişin verimliliği. Yazı yazmak
çağrılan fonksiyonda bu parametrelerin korunması örtük olarak belirtilir.
C++, tartışıldığı gibi, başvuru türü adı verilen özel bir işaretçi türü içerir.
Parametreler için sıklıkla kullanılan Bölüm 6'da. Referans parametreleri
işlev veya yöntemde dolaylı olarak başvurulmaz ve anlambilimi geçişlidir.
referans olarak. C++ aynı zamanda referans parametrelerinin uyumlu olması için tanımlanmasına izin verir.
stantlar. Örneğin, biz olabilir
Şekil 9.2
Bir olası yığın
uygulanması
ortak parametre-
geçme yöntemleri
İşlev başlığı: void sub ( int a, int b, int c, int d)
Ana işlev çağrısı : alt (w,x,y,z)
( w değerine göre, x sonucuna göre, y değer-sonuca göre, z referansına göre iletin)

Sayfa 428
9.5 Parametre Geçiş Yöntemleri
407
void fun( const int &p1, int p2, int &p3) { . . . }
burada p1 referans ile-pass ancak fonksiyonellik olarak değiştirilemez olan
tion eğlence , p2 pass-by-değeri ve p3 pass-by-referanstır. nei-
Ther p1 ne de p3 açıkça yer indirgenmedikleri edilmesi gereken eğlenceli .
Sabit parametreler ve mod içi parametreler tam olarak değil
benzer. Sabit parametreler modda açıkça uygulanır. Ancak,
Ada dışında tüm ortak zorunlu dillerde, modda
parametreler alt programda atanabilir.
değişiklikler asla karşılık gelen değerlerin değerlerine yansıtılmaz.
gerçek parametreler. Sabit parametreler asla atanamaz.
C ve C++'da olduğu gibi, tüm Java parametreleri değere göre iletilir.
Ancak, nesnelere yalnızca başvuru yoluyla erişilebildiği için
ence değişkenleri, nesne parametreleri aslında referansla geçirilir.
Parametre olarak iletilen bir nesne başvurusunun kendisi olamaz
çağrılan alt programda değiştirilebilir, başvurulan nesne
değişikliğe neden olacak bir yöntem varsa değiştirilir. Çünkü ref-
erence değişkenleri doğrudan skaler değişkenlere ve Java'ya işaret edemez
işaretçileri yok, skalerler referansla iletilemez
Java (skaler kutu içeren bir nesneye başvuru olmasına rağmen).
Ada ve Fortran 95+, programcının şunları belirtmesine izin verir:
her resmi parametrede mod, çıkış modu veya giriş modu.
C#'ın varsayılan parametre geçiş yöntemi, geçiştir-
değer. Referanstan geçiş, hem for-
mal parametresi ve ref ile karşılık gelen gerçek parametresi .
Örneğin, aşağıdaki C# iskelet yöntemini düşünün ve çağırın:
void sumer ( ref int eskiSum, int yeniBir) { . . . }
. . .
tüketicisi ( ref toplamı, newValue);
Sümer'e ilk parametre referansla iletilir; ikincisi geçti
değer.
C# ayrıca referanstan geçiş olan mod dışı parametreleri de destekler.
başlangıç ​​değerlerine ihtiyaç duymayan parametreler. Bu tür parametreler,
out değiştiricili resmi parametre listesi .
PHP'nin parametre geçişi, C#'ınkine benzer, ancak
gerçek parametre veya resmi parametre, referanstan geçişi belirtebilir. Geçmek-
by-referans, parametrelerden birinin veya her ikisinin önüne bir
ve işareti.
Perl, parametreleri iletmek için ilkel bir araç kullanır. Tüm gerçek para-
eterler örtük olarak @_ (her şeyden!) adlı önceden tanımlanmış bir diziye yerleştirilir . bu
alt program, bu diziden gerçek parametre değerlerini (veya adresleri) alır.
Bu diziyle ilgili en tuhaf şey, onun tarafından açığa çıkarılan büyülü doğasıdır.
öğelerinin aslında gerçek parametreler için takma adlar olduğu gerçeği. Orası-
önceden, çağrılan alt programda @_ öğesinin bir öğesi değiştirilirse, bu değişiklik
olduğunu varsayarak, çağrıdaki karşılık gelen gerçek parametreye yansıtılır.
tarih notu
ALGOL 60 tanıttı
adla geçiş yöntemi. Ayrıca
olarak değer geçişine izin verir
seçenek. öncelikle
uygulamada zorluk
onları, adla geçiş parametreleri
ALGOL'dan taşınmadı
60 sonraki dillere
popüler hale gelen (diğer
SIMULA 67'den daha fazla).
tarih notu
ALGOL W (Wirth ve Hoare,
1966) geçişi tanıttı
parametrenin değer-sonuç yöntemi
alternatif olarak geçmek
geçişin verimsizliği
adı ve sorunları
referans geçişi.

Sayfa 429
408
Bölüm 9 Alt Programlar
karşılık gelen gerçek parametre (gerçek parametre sayısının
resmi parametre sayısı ile aynıdır) ve bir değişkendir.
Python ve Ruby'nin parametre iletme yöntemine " pass-by-" denir.
ödev . Tüm veri değerleri nesneler olduğundan, her değişken bir referanstır.
bir obje. Geçişli atamada, gerçek parametre değeri,
resmi parametre. Bu nedenle, geçiş ataması aslında referanstan geçiştir,
çünkü tüm gerçek parametrelerin değeri referanslardır. Ancak, yalnızca
bazı durumlarda bu, referanstan-geçen parametre-anlambilimiyle sonuçlanır.
Örneğin, birçok nesne özünde değişmezdir. Saf nesne yönelimli
dil, bir atama ile bir değişkenin değerini değiştirme süreci
açıklamada olduğu gibi
x = x + 1
x tarafından başvurulan nesneyi değiştirmez . Bunun yerine, nesne referansını alır.
x ile girilir , onu 1 artırır , böylece yeni bir nesne (değeri ile) oluşturulur.
x + 1 ) ve ardından x'i yeni nesneye başvurmak için değiştirir . Yani, bir başvuru-
skaler bir nesneye ence bir alt programa iletilir, nesneye başvurulur
yerinde değiştirilemez. Referans değere göre iletildiğinden, hatta
Alt programda biçimsel parametre değiştirilse de, bu değişiklik
arayandaki gerçek parametre üzerinde hiçbir etkisi yoktur.
Şimdi, bir diziye bir başvurunun parametre olarak iletildiğini varsayalım. Eğer kor-
yanıt veren resmi parametreye yeni bir dizi nesnesi atanır, etkisi yoktur
arayan üzerinde. Ancak, resmi parametre bir değer atamak için kullanılıyorsa
dizinin elemanı, olduğu gibi
liste[3] = 47
gerçek parametre etkilenir. Yani, resmi referansın değiştirilmesi
parametrenin arayan üzerinde hiçbir etkisi yoktur, ancak dizinin bir öğesini değiştirir
bu bir parametrenin yaptığı gibi iletilir.
9.5.5 Tip Kontrol Parametreleri
Yazılım güvenilirliğinin aşağıdaki türlerden talep ettiği artık yaygın olarak kabul edilmektedir.
gerçek parametreler, karşılık gelen türlerle tutarlılık açısından kontrol edilmelidir.
biçimsel parametreler. Böyle bir tip kontrolü olmadan, küçük tipografik hatalar
oldukları için teşhis edilmesi zor olabilecek program hatalarına yol açabilir.
derleyici veya çalışma zamanı sistemi tarafından algılanmaz. Örneğin,
işlev çağrısı
sonuç = alt1(1)
gerçek parametre bir tamsayı sabitidir. sub1'in resmi parametresi ise
kayan nokta tipi, parametre tipi kontrolü olmadan hiçbir hata tespit edilmeyecektir.
ing. 1 tamsayı ve kayan nokta 1 aynı değere sahip olsa da,

Sayfa 430
9.5 Parametre Geçiş Yöntemleri
409
bu ikisinin temsilleri çok farklıdır. sub1 doğru üretemez
kayan nokta beklediğinde bir tamsayı gerçek parametre değeri verilen sonuç
değer.
Fortran 77 ve orijinal sürüm gibi erken programlama dilleri
C, parametre tipi denetimi gerektirmedi; çoğu sonraki diller gerektirir
o. Ancak, nispeten yeni olan Perl, JavaScript ve PHP dilleri böyle değildir.
C ve C++, parametre türü konusunda bazı özel tartışmalar gerektirir
kontrol etme. Orijinal C'de ne parametre sayısı ne de türleri
kontrol edildi. C89'da, fonksiyonların biçimsel parametreleri şurada tanımlanabilir:
iki yol. Orijinal C'deki gibi tanımlanabilirler; yani isimleri
parametreler parantez içinde listelenir ve bunlara ilişkin tür bildirimleri takip eder,
aşağıdaki fonksiyonda olduğu gibi:
çift günah(x)
çift x;
{ . . . }
Bu yöntemin kullanılması, tür denetimini önler, böylece aşağıdaki gibi çağrılara izin verir:
çift değer;
int sayısı;
. . .
değer = günah(sayı);
asla doğru olmasalar da yasaldır.
Orijinal C tanımlama yaklaşımına alternatif, proto- olarak adlandırılır.
biçimsel parametre türlerinin listeye dahil edildiği tür yöntemi,
çift günah ( çift x)
{ . . . }
Günahın bu versiyonu aynı çağrıyla, yani aşağıdakilerle çağrılırsa,
aynı zamanda yasaldır:
değer = günah(sayı);
Gerçek parametrenin türü ( int ) resmi parametreninkiyle karşılaştırılır.
parametre ( çift ). Eşleşmemelerine rağmen, int ikiye katlanmaya zorlanabilir
(genişleyen bir zorlamadır), böylece dönüştürme yapılır. dönüşüm değilse
mümkünse (örneğin, gerçek parametre bir dizi olsaydı) veya sayı
ber parametre yanlışsa, bir anlamsal hata algılanır. Yani C89'da,
kullanıcı, parametrelerin kontrol edilip edilmeyeceğini seçer.
C99 ve C++'da tüm fonksiyonların formel parametreleri protokolde olmalıdır.
formu yazın. Ancak, bazı parametreler için tip kontrolünden kaçınılabilir.
parametre listesinin son kısmını aşağıdaki gibi bir üç nokta ile değiştirerek
int printf( const char * format_string, . . .);

Sayfa 431
410
Bölüm 9 Alt Programlar
printf çağrısı , en az bir parametre, bir hazır bilgi için bir işaretçi içermelidir.
karakter dizesi. Bunun ötesinde, her şey (hiçbir şey dahil) yasaldır. bu
printf'in ek parametrelerin olup olmadığını belirleme şekli ,
string parametresinde format kodlarının varlığı. Örneğin, biçim
tamsayı çıktısı için kod %d'dir . Bu, aşağıdaki gibi dizenin bir parçası olarak görünür.
Takip etmek:
printf("Toplam %d\n", toplam);
% Söyler Printf bir daha parametre olduğunu işlevi.
Gerçekten resmiye parametre zorlaması ile ilgili ilginç bir konu daha vardır.
C#'da olduğu gibi, ilkellerin başvuru yoluyla iletilebildiği durumlarda kullanılır. Bir çağrı olduğunu varsayalım
yöntem , bir çift biçimli parametreye bir kayan nokta değeri iletir. Eğer bu parametre
değere göre geçirilir, kayan değer iki katına çıkmaya zorlanır ve herhangi bir olasılık yoktur.
lem. Bu özel zorlama çok faydalıdır, çünkü bir kütüphanenin şunları sağlamasına izin verir:
her ikisi için de kullanılabilecek alt programların çift versiyonları şamandıra ve çift
değerler. Ancak, parametrenin başvuru yoluyla iletildiğini varsayalım. değer ne zaman
arasında çifte biçimsel parametre döndürülen şamandıra gerçek parametre
arayanda, değer bulunduğu yerden taşar. Bu sorunu önlemek için C#
tipiyle tam olarak eşleşmesi için bir ref gerçek parametresinin türünü gerektirir.
karşılık gelen resmi parametre (zorlamaya izin verilmez).
Python ve Ruby'de parametrelerin tip kontrolü yoktur, çünkü tip-
bu dillerde ing farklı bir kavramdır. Nesnelerin türleri vardır, ancak değişkenler
yapma, bu nedenle resmi parametreler tipsizdir. Bu, tip fikrine izin vermez
parametreleri kontrol etme.
9.5.6 Parametre Olarak Çok Boyutlu Diziler
Dizin değerlerini eşlemek için kullanılan depolama eşleme işlevleri
bellekteki adreslere çok boyutlu dizilerin öğelerine yapılan başvurular
Bölüm 6'da ayrıntılı olarak tartışılmıştır. C ve C++ gibi bazı dillerde,
çok boyutlu bir dizi bir alt programa parametre olarak iletildiğinde,
derleyici, bu dizi için eşleme işlevini oluşturabilmelidir.
sadece alt programın metnini görmek (çağıran alt programı değil). Bu
true çünkü alt programlar programlardan ayrı olarak derlenebilir
bu onları çağırır. C'deki bir fonksiyona bir matris geçirme problemini düşünün.
C'deki çok boyutlu diziler gerçekten dizi dizileridir ve bunlar depolanır.
satır ana sırada. Aşağıdaki ana satır için bir depolama eşleme işlevidir.
tüm indekslerin alt sınırı 0 olduğunda matrisler için sıra ve eleman
boyut 1:
adres (mat[i, j]) = adres (mat[0,0]) + i *
sütun_sayısı + j
Bu eşleme işlevinin sütun sayısına ihtiyaç duyduğuna, ancak buna gerek duymadığına dikkat edin.
satır sayısı. Bu nedenle, C ve C++'da, bir matris a olarak geçirildiğinde

Sayfa 432
9.5 Parametre Geçiş Yöntemleri
411
parametre, biçimsel parametre, içindeki sütunların sayısını içermelidir.
ikinci parantez çifti. Bu, aşağıdaki iskelet C programında gösterilmiştir:
void fun( int matrix[][10]) {
. . . }
geçersiz ana() {
int mat[5][10];
. . .
eğlence(mat);
. . .
}
Bu matrisleri parametre olarak geçirme yöntemindeki sorun,
bir programcının matrisleri kabul edebilen bir fonksiyon yazmasına izin vermez.
farklı sayıda sütun; her matris için yeni bir fonksiyon yazılmalıdır
sütun sayısı farklıdır. Bu, aslında, esnek yazmaya izin vermez
işlevler çoklu işlevlerle ilgilenirse etkin bir şekilde yeniden kullanılabilen işlevler
mensional diziler. C ve C++'da, sorunun üstesinden gelmenin bir yolu vardır, çünkü
işaretçi aritmetiğinin dahil edilmesi. Matris bir işaretçi olarak geçirilebilir ve
matrisin gerçek boyutları da parametre olarak iletilebilir. Sonra
işlev, işaretçiyi kullanarak kullanıcı tarafından yazılan depolama eşleme işlevini değerlendirebilir
aritmetik, matrisin bir elemanına her başvurulduğunda. Örneğin,
aşağıdaki fonksiyon prototipini göz önünde bulundurun:
void fun( kayan *mat_ptr,
int sayı_satırlar,
int say_cols);
x değişkeninin değerini taşımak için aşağıdaki ifade kullanılabilir.
için [satır] [col] parametre matrisinin elemanına eğlence :
*(mat_ptr + (satır * num_cols) + sütun) = x;
Bu işe yaramasına rağmen, açıkça okunması zor ve içeriği nedeniyle
pleksite, hataya açıktır. Bunu okumanın zorluğu şu şekilde hafifletilebilir:
depolama eşleme işlevini tanımlamak için bir makro kullanma, örneğin
#define mat_ptr(r,c) (*mat_ptr + ((r) *
(sayı_kol) + (c)))
Bununla, ödev şu şekilde yazılabilir:
mat_ptr(satır,sütun) = x;
Diğer diller, sorunla başa çıkmak için farklı yaklaşımlar kullanır.
çok boyutlu dizileri geçmek. Ada derleyicileri tanımlanmış

Sayfa 433
412
Bölüm 9 Alt Programlar
zaman alt programında parametre olarak kullanılan tüm dizilerin boyutlarının boyutu
gram derlenir. Ada'da kısıtlanmamış dizi türleri resmi parametreler olabilir.
Kısıtlanmamış bir dizi türü, dizin aralıklarının dizinde verilmediği bir dizi türüdür.
dizi türü tanımı. Kısıtlanmamış dizi türlerinin değişkenlerinin tanımları
dizin aralıklarını içerir. Kısıtlamasız olarak geçirilen bir alt programdaki kod
dizi, ilişkili gerçek parametrenin dizin aralığı bilgisini alabilir
gibi parametrelerle. Örneğin, aşağıdaki tanımları göz önünde bulundurun:
type Mat_Type dizidir (Tamsayı aralığı <>,
Tamsayı aralığı <>) arasında Float;
Mat_1 : Mat_Type(1..100, 1..20);
Mat_Type dizilerinin öğelerinin toplamını döndüren bir işlev
tipi aşağıdaki gibidir:
işlev Sümer (Mal: içinde Mat_Type) dönüş Şamandıra olduğu
Toplam : Kayan := 0.0;
başlamak
için satır içinde Mat' aralığında (1) köprüsü
için Col içinde Mat' aralığı (2) ilmek
Toplam := Toplam + Mat(Satır, Sütun);
son döngü ; -- Col için . . .
son döngü ; -- Satır için . . .
return Sum;
sonu Sümer;
Aralık niteliği adlandırılmış subscript ait alt simge aralığı döndürür
gerçek parametre dizisi, bu nedenle bu, boyut veya dizin aralıklarından bağımsız olarak çalışır
parametrenin
Fortran'da sorun şu şekilde ele alınmaktadır. Resmi para-
diziler olan eterler, başlıktan sonra bir bildirime sahip olmalıdır. tek için-
boyutlu dizilerde, bu tür bildirimlerdeki alt simgeler önemsizdir. Ama için
çok boyutlu diziler, bu tür bildirimlerdeki alt simgeler derleyiciye izin verir
depolama eşleme işlevini oluşturmak için. Aşağıdaki örnek iskeleti düşünün
Fortran alt programı:
Altyordam Alt(Matris, Satırlar, Sütunlar, Sonuç)
Tamsayı, Amaç(Giriş) :: Satırlar, Sütunlar
Gerçek, Boyut(Satırlar, Sütunlar), Amaç(In) :: Matris
Real, Intent(In) :: Sonuç
. . .
Alt Program Alt Programını Bitir
Bu, Rows gerçek parametresi kullanılan değere sahip olduğu sürece mükemmel çalışır.
geçirilen matrisin tanımındaki satır sayısı için. Numara
Fortran dizileri sütun ana sırasına göre sakladığı için satır sayısı gereklidir. Eğer
geçirilecek dizi şu anda tanımlanmış boyutta yararlı verilerle dolu değil,

Sayfa 434
9.5 Parametre Geçiş Yöntemleri
413
daha sonra hem tanımlanmış dizin boyutları hem de doldurulmuş dizin boyutları,
alt program. Ardından, tanımlanan boyutlar yerel bildirimde kullanılır.
dizi ve doldurulmuş dizin boyutları, içinde bulunduğu hesaplamayı kontrol etmek için kullanılır.
dizi öğelerine başvurulur. Örneğin, aşağıdaki Fortran'ı düşünün
alt program:
Altyordam Matsum(Matrix, Rows, Cols, Filled_Rows,
Filled_Cols, Toplam)
Gerçek, Boyut(Satırlar, Sütunlar), Amaç(In) :: Matris
Integer, Intent(In) :: Rows, Cols, Filled_Rows,
Filled_Cols
Gerçek, Amaç(Çıkış) :: Toplam
Tamsayı :: Row_Index, Col_Index
Toplam = 0.0
Row_Index = 1, Filled_Rows yapın
Col_Index = 1, Filled_Cols yapın
Toplam = Toplam + Matris(Row_Index, Col_Index)
Bitir
Bitir
Altyordamı Sonlandır Matsum
Java ve C#, çok boyutlu dizileri parametre olarak geçirmek için bir teknik kullanır.
Ada'nınkine benzer eterler. Java ve C#'da diziler nesnelerdir. Onlar
hepsi tek boyutludur, ancak elemanlar dizi olabilir. Her dizi bir miras alır
uzunluğuna ayarlanan adlandırılmış sabit ( Java'da uzunluk ve C#'da Uzunluk )
dizi nesnesi oluşturulduğunda dizi. Bir matris için resmi parametre
aşağıdaki Java yönteminde olduğu gibi iki boş parantez seti ile görünür.
Ada örnek işlevi Sümer'in yaptığını yapar:
şamandıra sümer( şamandıra mat[][]) {
kayan nokta toplamı = 0.0f;
for ( int satır = 0; satır < mat. uzunluk ; satır++) {
for (int sütun = 0; sütun < mat[satır]. uzunluk ; sütun++) {
toplam += mat[satır][sütun];
} //** for (int satır . . .
} //** için (int sütun . . .
dönüş toplamı;
}
Her dizinin kendi uzunluk değeri olduğundan, bir matriste satırlar farklı olabilir.
ferent uzunlukları.
9.5.7 Tasarım Hususları
Parametre geçişini seçmede iki önemli husus söz konusudur
yöntemler: verimlilik ve tek yönlü mü yoksa iki yönlü veri aktarımının gerekli olup olmadığı.

Sayfa 435
414
Bölüm 9 Alt Programlar
Çağdaş yazılım mühendisliği ilkeleri, erişimin alt
alt program dışındaki verilere program kodu en aza indirilmelidir. Bununla
amaç akılda tutularak, mod içi parametreler hiçbir veri verisi olmadığında kullanılmalıdır.
arayana parametreler aracılığıyla döndürülür. Out-mode parametreleri olmalıdır
çağrılan alt programa ancak alt programa hiçbir veri aktarılmadığında kullanılır
verileri arayana geri iletmelidir. Son olarak, çıkış modu parametreleri
yalnızca verilerin arayan ile arasında her iki yönde de hareket etmesi gerektiğinde kullanılabilir.
denilen alt program.
Bu ilkeyle çelişen pratik bir düşünce var. Bazı-
tek yönlü parametre iletimi için erişim yollarının geçmesinin haklı olduğu zamanlar.
Örneğin, büyük bir dizi olmayan bir alt programa geçirileceği zaman
değiştirmek için tek yönlü bir yöntem tercih edilebilir. Ancak, geçiş değeri
tüm dizinin alt programın yerel bir depolama alanına taşınmasını gerektirir.
Bu hem zaman hem de mekan açısından maliyetli olacaktır. Bu nedenle, büyük diziler
genellikle referans olarak geçer. Ada 83'ün tanımlı olmasının nedeni tam olarak budur.
Bu, uygulayıcıların yapılandırılmış iki yöntem arasında seçim yapmasına izin verdi.
parametreler. C++ sabit referans parametreleri başka bir çözüm sunar. Bir diğeri
alternatif yaklaşım, kullanıcının yöntemler arasında seçim yapmasına izin vermek olacaktır.
Fonksiyonlar için parametre geçirme yönteminin seçimi, başka bir yöntem ile ilgilidir.
tasarım sorunu: işlevsel yan etkiler. Bu konu Bölüm 9.10'da tartışılmaktadır.
9.5.8 Parametre Geçişi Örnekleri
Aşağıdaki C işlevini göz önünde bulundurun:
geçersiz takas1( int a, int b) {
int sıcaklık = a;
a = b;
b = sıcaklık;
}
Bu işlevin ile çağrıldığını varsayalım.
takas1(c,d);
C'nin değere göre geçiş kullandığını hatırlayın. Swap1'in eylemleri şu şekilde tanımlanabilir:
aşağıdaki sözde kod:
bir = c
— İlk parametre değerini şuraya taşı
b = d
— İkinci parametre değerini içeri taşı
sıcaklık = bir
a = b
b = sıcaklık
a , d' nin değeriyle ve b , c'nin değeriyle bitmesine rağmen , c'nin değerleri
ve d değişmez çünkü arayana hiçbir şey geri iletilmez.

Sayfa 436
9.5 Parametre Geçiş Yöntemleri
415
İşaretçi parametreleriyle başa çıkmak için C takas işlevini değiştirebiliriz.
referansın etkisini elde etmek:
geçersiz takas2( int *a, int *b) {
int sıcaklık = *a;
*a = *b;
*b = sıcaklık;
}
swap2 ile çağrılabilir
takas2(&c, &d);
Swap2'nin eylemleri şu şekilde açıklanabilir:
a = &c — İlk parametre adresini şuraya taşı
b = &d — İkinci parametre adresini şuraya taşı
sıcaklık = *a
*a = *b
*b = sıcaklık
Bu durumda, takas işlemi başarılı: değerleri c ve d içindedir
gerçek değişti. swap2 , referans parametreleri kullanılarak C++ ile yazılabilir
aşağıdaki gibi:
geçersiz takas2( int &a, int &b) {
int sıcaklık = a;
a = b;
b = sıcaklık;
}
Bu basit takas işlemi Java'da mümkün değildir, çünkü ikisine de sahip değildir.
işaretçiler veya C++'ın tür referansları. Java'da bir referans değişkeni şunu gösterebilir:
yalnızca bir nesne, skaler bir değer değil.
Değere göre-sonucun semantiği,-geçen-sonucunun anlambilimi ile aynıdır.
aliasing'in dahil olduğu durumlar dışında referans. Ada'nın değere göre geçiş kullandığını hatırlayın.
mod dışı skaler parametreler için sonuç. Değere göre sonuca göre keşfetmek için,
değer geçişini kullandığını varsaydığımız aşağıdaki swap3 işlevini göz önünde bulundurun.
sonuç parametreleri. Ada'nınkine benzer bir söz dizimi ile yazılmıştır.
prosedür swap3 (a: çıkış tamsayı, b: dışarı Integer) olduğu
sıcaklık : Tamsayı;
başlamak
sıcaklık := bir;
bir := b;
b := sıcaklık;
son swap3;

Sayfa 437
416
Bölüm 9 Alt Programlar
Swap3'ün şununla çağrıldığını varsayalım:
takas3(c, d);
Bu çağrı ile swap3'ün eylemleri şunlardır:
addr_c = &c
— İlk parametre adresini şuraya taşı
addr_d = &d
— İkinci parametre adresini içeri taşı
a = *addr_c
— İlk parametre değerini şuraya taşı
b = *addr_d
— İkinci parametre değerini içeri taşı
sıcaklık = bir
a = b
b = sıcaklık
*addr_c = bir
— İlk parametre değerini dışarı taşı
*addr_d = b
— İkinci parametre değerini dışarı taşı
Böylece bir kez daha, bu takas alt programı doğru çalışıyor. Ardından, aramayı düşünün
swap3(i, liste[i]);
Bu durumda yapılacak işlemler
addr_i = &i
— İlk parametre adresini şuraya taşı
addr_listi= &list[i] — İkinci parametre adresini şuraya taşı
a = *addr_i
— İlk parametre değerini şuraya taşı
b = *addr_listi — İkinci parametre değerini şuraya taşı
sıcaklık = bir
a = b
b = sıcaklık
*addr_i = bir
— İlk parametre değerini dışarı taşı
*addr_listi = b — İkinci parametre değerini dışarı taşı
Yine, alt program doğru çalışır, çünkü bu durumda adresler
Parametrelerin değerlerini döndürmek için hangi zamanda hesaplanır
dönüş sırasında değil, arayın. Gerçek parametrenin adresleri ise-
Eterler dönüş anında hesaplanırsa sonuçlar yanlış olur.
Son olarak, takma ad geçişle ilgili olduğunda ne olduğunu araştırmalıyız.
değere göre sonuç ve referansa göre geçiş. Aşağıdaki iskelet programını göz önünde bulundurun
C-benzeri sözdiziminde yazılmış:
int ben = 3; /* i global bir değişkendir */
geçersiz eğlence( int a, int b) {
ben = b;
}
geçersiz ana() {
int listesi[10];

Sayfa 438
9.6 Alt Program Olan Parametreler 417
liste[i] = 5;
fun(i, liste[i]);
}
Olarak eğlence , pas-referans ile, kullanıldığı takdirde i ve bir takma vardır. Eğer değere göre-sonuç
kullanılır, i ve a takma ad değildir. Eğlence eylemleri , değere göre geçiş olduğunu varsayarak-
sonuç, aşağıdaki gibidir:
addr_i = &i
— İlk parametre adresini şuraya taşı
addr_listi = &list[i] — İkinci parametre adresini şuraya taşı
a = *addr_i
— İlk parametre değerini şuraya taşı
b = *addr_listi — İkinci parametre değerini şuraya taşı
ben = b
— i'yi 5'e ayarlar
*addr_i = bir
— İlk parametre değerini dışarı taşı
*addr_listi = b — İkinci parametre değerini dışarı taşı
Bu durumda, küresel, atama i içinde eğlenceli , değerini değiştirir 3'e kadar
5 , ancak ilk resmi parametrenin geri kopyası (en son satırdan ikinci satır)
örnek) 3 olarak ayarlar . Buradaki önemli gözlem, eğer yoldan geçerse-
referans kullanıldığında, sonuç, geri kopyanın anlambilimin bir parçası olmadığıdır,
ve ben 5 kalıyorum . Ayrıca, ikinci parametrenin adresinin
eğlencenin başlangıcında hesaplandığında , global i'deki herhangi bir değişikliğin hiçbir etkisi yoktur.
sonunda list[i] değerini döndürmek için kullanılan adres .
9.6 Alt Program Olan Parametreler
Programlamada, en uygun olan bir dizi durum ortaya çıkar.
alt program adları diğer alt programlara parametre olarak gönderilebiliyorsa işlenir.
Bunların yaygın bir örneği, bir alt programın bazılarını örneklemesi gerektiğinde ortaya çıkar.
matematiksel fonksiyon. Örneğin, sayısal işlemler yapan bir alt program
gration, fonksiyonu örnekleyerek bir fonksiyonun grafiğinin altındaki alanı tahmin eder.
birkaç farklı noktada yer almaktadır. Böyle bir alt program yazıldığında,
verilen herhangi bir işlev için kullanılabilir olmalıdır; bunun için yeniden yazılması gerekmez
entegre edilmesi gereken her fonksiyon. Bu nedenle, adının olması doğaldır.
entegre edilecek matematiksel işlevi değerlendiren bir program işlevi
parametre olarak entegre eden alt programa gönderilir.
Fikir doğal ve görünüşte basit olsa da, nasıl yapıldığına dair ayrıntılar
işler kafa karıştırabilir. Yalnızca alt program kodunun iletimi
gerekirse, tek bir işaretçi geçerek yapılabilir. Ancak iki uyum
katyonlar oluşur.
İlk olarak, aktivasyonların parametrelerini kontrol eden tip meselesi var.
parametre olarak geçirilen alt programın C ve C++'da fonksiyonlar
parametre olarak geçirilemez, ancak işlevlere yönelik işaretçiler geçebilir. türü bir
bir işleve işaretçi, işlevin protokolünü içerir. çünkü protokol
tüm parametre türlerini içerir, bu tür parametreler tamamen tip kontrol edilebilir.

Sayfa 439
418
Bölüm 9 Alt Programlar
Fortran 95+, alt program için parametre türleri sağlayan bir mekanizmaya sahiptir.
Parametre olarak geçirilen gramlar kontrol edilmelidir.
Alt programlar olan parametrelerle ilgili ikinci karmaşıklık belirir.
yalnızca iç içe alt programlara izin veren dillerle. Sorun, referansın ne olduğudur.
geçirilen alt programın yürütülmesi için ortam kullanılmalıdır. Orası
üç seçenek vardır:
• Geçen alt programı yürürlüğe koyan çağrı ifadesinin ortamı
( sığ bağlama )
• Geçilen alt programın tanımının ortamı ( derin
bağlayıcı )
• Bir alt program olarak geçen çağrı ifadesinin ortamı
gerçek parametre ( ad hoc bağlama )
JavaScript sözdizimi ile yazılmış aşağıdaki örnek program,
bu seçimleri gösterir:
işlev alt1() {
var x;
işlev alt2() {
uyarı(x); // x değerine sahip bir iletişim kutusu oluşturur
};
işlev alt3() {
var x;
x = 3;
alt4(alt2);
};
işlev alt4(altx) {
var x;
x = 4;
altx();
};
x = 1;
alt3();
};
sub2 içinde çağrıldığında sub4'ün yürütülmesini düşünün . sığ için
bağlayıcı, bu yürütmenin referans ortamı sub4'ünkidir , bu nedenle
referans x olarak sub2 yerel bağlı olduğu , x in sub4te ve çıkış
programı 4'tür . Derin, nin referans ortamını ciltleme için sub2 ‘ın Ser-
tion olduğu ait sub1 referans böylece, x in sub2 yerel bağlı x içinde
sub1 ve çıktı 1'dir . Ad hoc ciltleme için, bağlayıcı yerel etmektir x içinde
sub3 ve çıktı 3'tür .
Bazı durumlarda, bir alt program bildiren alt program bunu da geçer.
parametre olarak alt program. Bu durumlarda, derin ciltleme ve ad hoc ciltleme
aynıdır. Ad hoc bağlama hiç kullanılmadı çünkü tahmin edilebilir,

Sayfa 440
9.7 Alt Programları Dolaylı Olarak Çağırma 419
prosedürün parametre olarak göründüğü ortam
geçirilen alt programla doğal bir bağlantısı yoktur.
Sığ bağlama, statik kapsamlı alan için uygun değildir.
iç içe alt programlarla göstergeler. Örneğin, varsayalım
prosedür Gönderici , parametre olarak Gönderilen prosedürü geçer
alıcı prosedürüne . Sorun şu ki, Alıcı
Sent'in statik ortamında olmayabilir , bu nedenle
Gönderilen'in Alıcı değişkenlerine erişmesi çok doğal değil .
Öte yandan, böyle bir dilde son derece normaldir.
parametre olarak gönderilen de dahil olmak üzere herhangi bir alt program,
sözlüksel konumu tarafından belirlenen referans ortamı
onun tanımı. Bu nedenle, bu diller için daha mantıklıdır.
derin ciltleme kullanın. Bazı dinamik kapsamlı diller sığ kullanır
bağlayıcı.
9.7 Alt Programları Dolaylı Olarak Çağırmak
Alt programların bağımsız olarak adlandırılması gereken durumlar vardır.
doğrudan. Bunlar genellikle belirli bir alt program
çağrılacak çalışma zamanı kadar bilinmemektedir. Alt programa çağrı yapılır
ayarlanmış olan alt programa bir işaretçi veya referans aracılığıyla
arama yapılmadan önce yürütme. En yaygın iki uygulama
dolaylı alt program çağrıları, grafik kullanıcı arayüzlerinde olay işleme içindir,
Artık neredeyse tüm Web uygulamalarının bir parçası olan ve Web dışı birçok
uygulamalar ve bir alt programın çağrıldığı ve talimat verildiği geri aramalar için
aranan alt program işini bitirdiğinde arayanı bilgilendirmek için. Olarak
her zaman, ilgimiz bu özel programlama türleri değil, daha çok
onlar için programlama dili desteği.
Alt programları dolaylı olarak çağırma kavramı yeni bir gelişme değildir.
oped kavramı. C ve C++, bir programın bir işleve işaretçi tanımlamasına izin verir,
hangi fonksiyon aracılığıyla çağrılabilir. C++'da işlevlere yönelik işaretçiler
fonksiyonun dönüş tipine ve parametre tipine göre yazılır, yani
böyle bir işaretçi yalnızca belirli bir protokole sahip işlevleri işaret edebilir.
Örneğin, aşağıdaki bildirim, işaret edebilen bir işaretçiyi ( pfun ) tanımlar.
parametre olarak bir kayan nokta ve bir int alan ve bir değer döndüren herhangi bir işleve
yüzer :
kayan nokta (*pfun)( kayan nokta , int );
Bu işaretçiyle aynı protokole sahip herhangi bir işlev, başlangıç ​​olarak kullanılabilir.
Bu işaretçinin değeri veya bir programdaki işaretçiye atanabilir. C ve C++'da,
olmayan bir dizi adı gibi, parantezleri olmayan bir işlev adı
aşağıdaki parantezler, işlevin (veya dizinin) adresidir. Yani, her ikisi de fol-
alçalma, bir başlangıç ​​değeri vermenin veya bir işaretçiye değer atamanın yasal yollarıdır.
bir işleve:
tarih notu
Pascal'ın orijinal tanımı
(Jensen ve Wirth, 1974)
izin verilen alt programlar
olmadan parametre olarak geçti
parametre türleri dahil
bilgi. bağımsız ise
derleme mümkündür (ki
orijinal Pascal'da değildi),
derleyiciye bile izin verilmiyor
doğru numarayı kontrol etmek için
parametreler. yokluğunda
bağımsız derleme,
parametre kontrolü
tutarlılık mümkündür ancak
çok karmaşık bir görev ve genellikle
yapılmaz.

Sayfa 441
420
Bölüm 9 Alt Programlar
int myfun2 ( int , int ); // Bir fonksiyon bildirimi
int (*pfun2)( int , int ) = eğlencem2; // Bir işaretçi oluşturun ve
// başlat
// myfun2'yi işaret edecek
pfun2 = myfun2; // Bir fonksiyonun adresini bir fonksiyona atamak
// Işaretçi
myfun2 işlevi artık aşağıdaki ifadelerden biri ile çağrılabilir:
(*pfun2)(birinci, ikinci);
pfun2(birinci, ikinci);
Bunlardan ilki , yasal olan pfun2 işaretçisinin referansını açıkça kaldırır , ancak
gereksiz.
C ve C++ fonksiyon işaretçileri parametre olarak gönderilebilir ve döndürülebilir.
işlevlerden, işlevler bunlardan herhangi birinde doğrudan kullanılamasa da
roller.
C#'da yöntem işaretçilerinin gücü ve esnekliği,
onları nesneler. Bunlara delegeler denir , çünkü bir yöntemi çağırmak yerine,
bir program, bu eylemi bir temsilciye devreder.
Bir temsilci kullanmak için önce temsilci sınıfı belirli bir sınıfla tanımlanmalıdır.
yöntem protokolü. Bir temsilcinin somutlaştırılması, bir yöntemin adını tutar
delegenin arayabileceği protokolü ile. Bir bildirimin sözdizimi
bir temsilci, ayrılmış olması dışında bir yöntem bildirimininkiyle aynıdır.
sözcük temsilcisi , dönüş türünden hemen önce eklenir. Örneğin,
aşağıdakilere sahip olun:
genel temsilci int Change( int x);
Bu temsilci, int olarak alan herhangi bir yöntemle başlatılabilir.
parametre ve bir int döndürür . Örneğin, aşağıdaki yöntemi göz önünde bulundurun
beyan:
statik int fun1( int x);
Temsilci Değişikliği , bunun adı gönderilerek başlatılabilir.
aşağıdaki gibi temsilcinin yapıcısına yöntem:
Değiştir chgfun1 = new Değiştir( fun1 );
Bu, aşağıdaki şekilde kısaltılabilir:
chgfun1 = fun1'i değiştirin;
Bir örnek çağrısı aşağıdadır FUN1 temsilci aracılığıyla chgfun1 :
chgfun1(12);

Sayfa 442
9.8 Aşırı Yüklenmiş Alt Programlar 421
Bir temsilci sınıfının nesneleri birden fazla yöntemi depolayabilir. Bir saniye
yöntem , aşağıdaki gibi += operatörü kullanılarak eklenebilir :
chgfun1 += fun2'yi değiştirin;
Bu yerler FUN2 içinde chgfun1 daha önce olsaydı bile, temsilci
değer boş . Bir temsilci örneğinde depolanan yöntemlerin tümü, içinde çağrılır.
örneğe yerleştirildikleri sıra. Buna çok noktaya yayın del-
egale . Yöntemler tarafından ne döndürülürse döndürülsün, yalnızca değer veya nesne
son aranan tarafından döndürülür. Tabii ki, bu çoğu durumda
durumlarda, void , çok noktaya yayın temsilcisi aracılığıyla çağrılan yöntemler tarafından döndürülür.
Örneğimizde, temsilciye Change statik bir yöntem yerleştirilir . Misal
yöntemler ayrıca bir temsilci aracılığıyla da çağrılabilir, bu durumda temsilcinin
yönteme bir referans depolayın. Delegeler de genel olabilir.
Temsilciler, .NET uygulamaları tarafından olay işleme için kullanılır. Onlar ayrıca
kapamaları uygulamak için kullanılır (bkz. Bölüm 9.12).
C ve C++'da olduğu gibi, Python'da bir fonksiyonun adı
aşağıdaki parantezler bu işlevin bir göstergesidir. Ada 95 için işaretçiler var
alt programlar, ancak Java yok. Python ve Ruby'de ve çoğu işlevde
alt programlara veri gibi davranılır, böylece atanabilirler.
değişkenlere. Bu nedenle, bu dillerde, işaretçilere çok az ihtiyaç vardır.
alt programlar.
9.8 Aşırı Yüklenmiş Alt Programlar
Aşırı yüklenmiş bir operatör, birden çok anlamı olan bir operatördür. bir anlamı
aşırı yüklenmiş bir operatörün belirli bir örneği, türlerine göre belirlenir.
işlenenler. Örneğin, * operatörünün bir dizinde iki kayan nokta işleneni varsa
Java programı, kayan noktalı çarpmayı belirtir. Ancak aynı operatör
iki tamsayı işleneni vardır, tamsayı çarpmasını belirtir.
Aşırı yüklenmiş bir alt program, aynı ada sahip bir alt programdır.
aynı referans ortamında başka bir alt program. Her sürüm bir
aşırı yüklenmiş alt programın benzersiz bir protokolü olmalıdır; yani, farklı olmalı-
parametrelerinin sayısı, sırası veya türü bakımından diğerlerinden farklıdır ve
bir işlev ise, ssible dönüş türünde. Aşırı yüklenmiş bir çağrının anlamı
alt program, gerçek parametre listesi (ve/veya muhtemelen
bir işlev durumunda, döndürülen değerin). Gerekli olmasa da,
aşırı yüklenmiş alt programlar genellikle aynı işlemi uygular.
C++, Java, Ada ve C#, önceden tanımlanmış aşırı yüklenmiş alt programları içerir. İçin
örneğin, C++, Java ve C#'daki birçok sınıf, aşırı yüklenmiş kuruculara sahiptir.
Aşırı yüklenmiş bir alt programın her bir versiyonunun benzersiz bir parametre pro-
dosyasında, derleyici, kendilerine yapılan çağrıların oluşumlarını farklı şekilde netleştirebilir.
parametreleri yazın. Ne yazık ki, o kadar basit değil. Parametre zorlamaları, ne zaman
izin verilirse, anlam ayrımı sürecini büyük ölçüde karmaşık hale getirir. Basitçe ifade edilen,
sorun şu ki, hiçbir yöntemin parametre profilinin sayısı ve türleri ile eşleşmezse

Sayfa 443
422
Bölüm 9 Alt Programlar
bir yöntem çağrısındaki gerçek parametreler, ancak iki veya daha fazla yöntemin parametreleri vardır.
zorlamalar yoluyla eşleştirilebilen eter profilleri, hangi yöntemin
aranan? Bir dil tasarımcısının bu soruyu cevaplayabilmesi için karar vermesi gerekir.
derleyicinin seçebilmesi için tüm farklı zorlamaların nasıl sıralanacağı
çağrıyla "en iyi" eşleşen yöntem. Bu karmaşık bir görev olabilir. Altında-
Bu sürecin karmaşıklık düzeyine dayanmak, okuyucunun aşağıdakilere başvurmasını öneririz.
C++'da kullanılan yöntem çağrılarının belirsizliğini giderme kuralları (Stroustrup, 1997).
C++, Java ve C# karma mod ifadelerine izin verdiğinden, dönüş türü
aşırı yüklenmiş işlevlerin (veya yöntemlerin) belirsizliğinin giderilmesiyle ilgisizdir. Bağlam
çağrının dönüş tipinin belirlenmesine izin vermez. Örneğin, eğer bir
C++ programının fun adında iki işlevi vardır ve her ikisi de bir int parametresi alır ancak
biri bir int , diğeri bir float döndürür , program derlenmez,
çünkü derleyici hangi eğlence sürümünün kullanılması gerektiğini belirleyemedi .
Kullanıcıların aynı zamanda alt programların birden çok versiyonunu yazmalarına da izin verilir.
Ada, Java, C++, C# ve F# ile aynı ad. Bir kez daha, C++, Java ve C#'da
en yaygın kullanıcı tanımlı aşırı yükleme yöntemleri yapıcılardır.
Varsayılan parametrelere sahip aşırı yüklenmiş alt programlar belirsizliğe yol açabilir.
ous alt program çağrıları. Örneğin, aşağıdaki C++ kodunu göz önünde bulundurun:
void fun( kayan nokta b = 0.0);
boş eğlence();
. . .
eğlence();
Çağrı belirsizdir ve derleme hatasına neden olur.
9.9 Genel Alt Programlar
Yazılımın yeniden kullanımı, yazılım üretkenliğine önemli bir katkıda bulunabilir. Bir
Yazılımın yeniden kullanılabilirliğini artırmanın yolu, farklılık yaratma ihtiyacını azaltmaktır.
farklı türlerde aynı algoritmayı uygulayan farklı alt programlar
veri. Örneğin, bir programcının dört farklı sıralama yazması gerekmemelidir.
sadece eleman tipinde farklılık gösteren dört diziyi sıralamak için alt programlar.
Bir polimorfik alt program, farklı türlerde parametreleri alır.
şiddetli aktivasyonlar. Aşırı yüklenmiş alt programlar, belirli bir tür poli-
morfizm ad hoc polimorfizm olarak adlandırılır . Aşırı yüklenmiş alt programların
benzer şekilde davranın.
Nesne yönelimli programlamayı destekleyen diller genellikle alt
tip polimorfizm. Alt tip polimorfizmi , T tipi bir değişkenin
T türündeki herhangi bir nesneye veya T'den türetilen herhangi bir türe erişebilir.
Daha genel bir polimorfizm türü şu yöntemlerle sağlanır:
Python ve Ruby. Bu dillerdeki değişkenlerin türleri olmadığını hatırlayın,
bu nedenle biçimsel parametrelerin türleri yoktur. Bu nedenle, herhangi bir yöntem için bir yöntem işe yarayacaktır.
operatörler resmi parametrelerde kullanıldığı sürece gerçek parametrenin türü
yöntemde tanımlanmıştır.

Sayfa 444
9.9 Genel Alt Programlar 423
Parametrik polimorfizm , bir alt program tarafından sağlanır.
türleri tanımlayan tür ifadelerinde kullanılan genel parametreler
alt program parametrelerinin Bu tür alt pro-
gramlara farklı genel parametreler verilebilir, bu da alt programlar üretir.
farklı türde parametreler alır. Tüm alt programların parametrik tanımları
aynı şekilde davran. Parametrik olarak polimorfik alt programlar genellikle
genel alt programlar Ada, C++, Java 5.0+, C# 2005+ ve F# bir tür sağlar
derleme zamanı parametrik polimorfizmi.
9.9.1 C++'da Genel İşlevler
C++'daki genel işlevler, şablon işlevlerinin açıklayıcı adına sahiptir . bu
bir şablon fonksiyonunun tanımı genel forma sahiptir
şablon < şablon parametreleri >
—şablon parametrelerini içerebilen bir fonksiyon tanımı
Bir şablon parametresi (en az bir tane olmalıdır) formlardan birine sahiptir
sınıf tanımlayıcısı
tür adı tanımlayıcısı
Sınıf formu, tür adları için kullanılır. Typename bir şekilde geçirilmesi için kullanılan
şablon işlevine bir değer. Örneğin, bazen uygun
şablon işlevinde bir dizinin boyutu için bir tamsayı değeri iletin.
Bir şablon başka bir şablon alabilir, pratikte genellikle bir şablon sınıfı
parametre olarak kullanıcı tanımlı bir jenerik türü tanımlayan, ancak dikkate almadığımız
bu seçenek burada. 8
Bir şablon işlevine örnek olarak aşağıdakileri göz önünde bulundurun:
şablon < sınıf Tipi>
Maksimum yazın(Önce yazın, İkinci yazın) {
ilk > ikinci dön ? birinci, ikinci;
}
Burada Tür , işlevin üzerinde çalışacağı veri türünü belirten parametredir.
faaliyet gösterecek. Bu şablon işlevi, herhangi bir tür için başlatılabilir.
> operatörünün tanımlı olduğu. Örneğin, int ile somutlaştırılsaydı
parametre olarak,
int max( int birinci, int saniye) {
ilk > ikinci dön? birinci, ikinci;
}
8. Şablon sınıfları Bölüm 11'de tartışılmaktadır.

Sayfa 445
424
Bölüm 9 Alt Programlar
Bu süreç bir makro olarak tanımlanabilse de, bir makronun
parametreler ile ifadeler olsaydı doğru çalışmamanın dezavantajı
yan etkiler. Örneğin, makronun şu şekilde tanımlandığını varsayalım:
#define max(a, b) ((a) > (b)) ? (a) : (b)
Bu tanım, herhangi bir sayısal tür için işe yaraması bakımından geneldir.
Ancak, bir parametre ile çağrıldığında her zaman doğru çalışmaz.
gibi bir yan etki
maks(x++, y)
hangi üretir
((x++) > (y) ? (x++) : (y))
Değeri her x ve daha büyük olan y , x artırılır
iki kere.
C++ şablon işlevleri, işlev
çağrıda veya adresi & operatörü ile alındığında adlandırılır . İçin
örneğin, tanımlanan örnek şablon işlevi iki kez başlatılır
aşağıdaki kod segmentiyle—bir kez int tipi parametreler için ve bir kez
karakter tipi parametreleri:
int a, b, c;
karakter d, e, f;
. . .
c = maks(a, b);
f = maks(d, e);
Aşağıdaki, bir C++ genel sıralama alt programıdır:
şablon <sınıf Türü>
hükümsüz generic_sort (Tip listesi [], int len) {
int üst, alt;
Tip sıcaklığı;
for (üst = 0; üst < len - 2; üst++)
for (alt = üst + 1; alt < len - 1; alt++)
if (list[üst] > liste[alt]) {
temp = liste[üst];
liste[üst] = liste[alt];
liste[alt] = sıcaklık;
} //** if'nin sonu (list[top] . . .
} //** Generic_sort'un sonu
Aşağıdaki, bu şablon işlevinin örnek bir örneğidir:

Sayfa 446
9.9 Genel Alt Programlar 425
float flt_list[100];
. . .
general_sort(flt_list, 100);
C++'ın şablonlu işlevleri, bir alt programın bir tür zayıf kuzenidir.
biçimsel parametre türlerinin türlere dinamik olarak bağlı olduğu
bir çağrıdaki gerçek parametrelerin Bu durumda, kodun yalnızca tek bir kopyası
gereklidir, oysa C++ yaklaşımıyla derlemede bir kopya oluşturulmalıdır
gerekli olan her farklı tip için zaman ve alt programın bağlanması
alt programlara yapılan çağrılar statiktir.
9.9.2 Java 5.0'daki Genel Yöntemler
Java 5.0'da Java'ya genel türler ve yöntemler için destek eklendi. İsim
Java 5.0'daki genel bir sınıfın adı, bir ad ve ardından bir veya daha fazla
köşeli parantezlerle ayrılmış tür değişkenleri. Örneğin,
jenerik_sınıfı <T>
burada T , tür değişkenidir. Genel türler daha ayrıntılı olarak tartışılmaktadır.
Bölüm 11.
Java'nın genel yöntemleri, C++'ın genel alt programlarından farklıdır.
birkaç önemli yol. İlk olarak, genel parametreler sınıflar olmalıdır;
ilkel tipler olmasın. Bu gereksinim, genel bir yönteme izin vermez.
dizilerin bileşen türlerinin bulunduğu C++'daki örneğimizi taklit eder.
genel ve ilkel olabilir. Java'da dizilerin bileşenleri (tersine
kaplara) genel olamaz. İkincisi, Java jenerik yöntemleri
herhangi bir sayıda somutlaştırılabilir, kodun yalnızca bir kopyası oluşturulur. bu
ham yöntem olarak adlandırılan genel bir yöntemin dahili versiyonu çalışır.
üzerinde Nesne sınıfı nesneleri. Bir jeneriğin jenerik değerinin ortaya çıktığı noktada
yöntem döndürüldüğünde, derleyici uygun türe bir döküm ekler. Üçüncüsü, içinde
Java, geçilebilecek sınıfların aralığında kısıtlamalar belirtilebilir
genel parametreler olarak genel yönteme. Bu tür kısıtlamalara denir
sınırlar .
Genel bir Java 5.0 yöntemine örnek olarak aşağıdaki iskeleti göz önünde bulundurun:
yöntem tanımı:
genel statik <T> T doIt(T[] listesi) {
. . .
}
Bu, genel bir öğe dizisini alan doIt adlı bir yöntemi tanımlar.
tip. Jenerik tip adıdır T ve bir dizi olmalıdır. takip ediliyor
doIt için örnek bir çağrı :
doIt<String>(myList);

Sayfa 447
426
Bölüm 9 Alt Programlar
Şimdi, üzerinde bir sınırı olan aşağıdaki doIt sürümünü düşünün.
genel parametre:
public static <T Karşılaştırılabilir'i genişletir > T doIt(T[] listesi) {
. . .
}
Bu, öğeleri olan genel bir dizi parametresini alan bir yöntemi tanımlar.
Comparable arabirimini uygulayan bir sınıfın . Kısıtlama budur veya
genel parametreye bağlı. Ayrılmış kelime uzanır ima ediyor gibi görünüyor
jenerik sınıfın aşağıdaki sınıfın alt sınıflarını oluşturduğunu. Ancak bu bağlamda,
uzatmanın farklı bir anlamı vardır. <T BoundingType'ı genişletiyor > ifadesi
T'nin sınırlayıcı türün bir "alt türü" olması gerektiğini belirtir . Yani, bu bağlamda,
genişletir , genel sınıfın (veya arabirimin) sınırlayıcı sınıfı genişlettiği anlamına gelir
(sınıfsa sınır) veya sınırlayıcı arabirimi uygular (bağlıysa
bir arayüz). Sınır, herhangi bir somutlaştırmanın öğelerinin
jenerik, Comparable yöntemiyle karşılaştırılabilir , CompareTo .
Genel bir yöntemin genel türü üzerinde iki veya daha fazla kısıtlaması varsa, bunlar
Genişletilmiş yan tümceye ve işaretleri ( & ) ile ayrılarak eklenir . Ayrıca, genel
metotlar birden fazla genel parametreye sahip olabilir.
Java 5.0, joker karakter türlerini destekler . Örneğin, Koleksiyon<?> bir vahşi-
koleksiyon sınıfları için kart türü. Bu tür, herhangi bir koleksiyon türü için kullanılabilir
herhangi bir sınıf bileşeninin Örneğin, aşağıdaki genel yöntemi göz önünde bulundurun:
void printCollection(Koleksiyon<?> c) ​​{
for (Nesne e: c) {
System.out.println(e);
}
}
Bu yöntem , sınıftan bağımsız olarak herhangi bir Koleksiyon sınıfının öğelerini yazdırır.
bileşenlerinden. Joker karakter türündeki nesnelere biraz özen gösterilmelidir.
Örneğin, bu türden belirli bir nesnenin bileşenlerinin bir
type, diğer type nesneleri koleksiyona eklenemez. Örneğin, şunları göz önünde bulundurun:
Koleksiyon<?> c = new ArrayList<String>();
Bu koleksiyona bir şey koymak için add yöntemini kullanmak yasa dışı olur.
türü String değilse .
Joker karakter türleri, joker karakter olmayan türlerde olduğu gibi kısıtlanabilir.
Bu türlere sınırlı joker karakter türleri denir . Örneğin, aşağıdakileri göz önünde bulundurun-
yöntem başlığı:
public void drawAll(ArrayList<? Shape'i genişletir > şeyler)
Buradaki genel tür, Shape sınıfının bir alt sınıfı olan bir joker karakter türüdür . Bu
türü Shape öğesinin alt sınıfı olan herhangi bir nesneyi çizmek için yöntem yazılabilir .

Sayfa 448
9.9 Genel Alt Programlar 427
9.9.3 C# 2005'te Genel Yöntemler
C# 2005'in genel yöntemleri, yetenek olarak Java 5.0'ınkilere benzerdir,
Joker karakter türleri için destek olmaması dışında. C# 2005'in benzersiz bir özelliği
genel yöntemler, bir çağrıdaki gerçek tür parametrelerinin, aşağıdaki durumlarda atlanabilmesidir.
derleyici belirtilmemiş türü çıkarabilir. Örneğin, aşağıdakileri göz önünde bulundurun
iskelet sınıfı tanımı:
sınıf Sınıfım {
genel statik T DoIt<T>(T p1) {
. . .
}
}
DoIt yöntemi , aşağıdaki durumlarda genel parametre belirtilmeden çağrılabilir:
derleyici, çağrıdaki gerçek parametreden genel türü çıkarabilir.
Örneğin, aşağıdaki aramaların her ikisi de yasaldır:
int myInt = Sınıfım.DoIt(17); // DoIt'i çağırır< int >
string myStr = MyClass.DoIt('elmalar');
// DoIt< dizesini çağırır >
9.9.4 F#'da Genel Fonksiyonlar
F# tür çıkarım sistemi, her zaman
parametreler veya bir işlevin dönüş türü. Durum böyle olunca bazıları için
F#, parametreler ve dönüş değeri için genel bir tür çıkarır.
Buna otomatik genelleme denir . Örneğin, aşağıdakileri göz önünde bulundurun
fonksiyon tanımı:
izin GetLast (a, b, c) = C ;;
Hiçbir tür bilgisi dahil edilmediğinden, parametre türleri ve
dönüş değerinin tümü genel olarak kabul edilir. Bu fonksiyon olmadığı için
herhangi bir hesaplamayı dahil edin, bu basit bir genel işlevdir.
Fonksiyonlar, aşağıdaki gibi genel parametrelere sahip olacak şekilde tanımlanabilir.
örnek:
izin printPair (x: 'a) (y' a) =
printfn "%A %A" xy;;
% A biçimi özelliklerinde türü için. Yazının önündeki kesme işareti
adlı a, bunun genel bir tür olduğunu belirtir. 9 Bu işlev tanımı çalışır (
genel parametreler) çünkü tür kısıtlamalı bir işlem dahil değildir.
9. a ile ilgili özel bir şey yoktur—herhangi bir yasal tanımlayıcı olabilir. Kural olarak, küçük harf
Alfabenin başındaki harfler kullanılır.

Sayfa 449
428
Bölüm 9 Alt Programlar
Aritmetik işleçler, tür kısıtlamalı işlemlere örnektir. Sınav için-
ple, aşağıdaki işlev tanımını göz önünde bulundurun:
izin toplayıcı xy = x + y ;;
Tür çıkarımı, x ve y'nin türünü ve dönüş değerini int olarak ayarlar . Çünkü
F#'da tür zorlaması yoktur, aşağıdaki çağrı yasa dışıdır:
toplayıcı 2.5 3.6;;
Parametrelerin türü genel olarak ayarlansa bile, + operatörü
türlerini neden x ve y için int .
Genel tür, aşağıdaki gibi, köşeli parantez içinde de açıkça belirtilebilir.
devamındaki:
let printPair2 <T> xy =
printfn "%A %A" xy;;
Bu işlev , aşağıdaki gibi bir tür 10 ile çağrılmalıdır :
printPair2<float> 3.5 2.4;;
Tür çıkarımı ve tür zorlamalarının olmaması nedeniyle, F# jenerik
fonksiyonlar, özellikle sayısal hesaplamalar için, bunlardan çok daha az kullanışlıdır.
C++, Java 5.0+ ve C# 2005+.
9.10 Fonksiyonlar için Tasarım Konuları
Aşağıdaki tasarım sorunları, işlevlere özeldir:
• Yan etkilere izin veriliyor mu?
• Ne tür değerler döndürülebilir?
• Kaç değer döndürülebilir?
9.10.1 Fonksiyonel Yan Etkiler
İfadelerde çağrılan fonksiyonların yan etki problemlerinden dolayı,
Bölüm 5'te açıklandığı gibi, işlev parametreleri her zaman modda olmalıdır
parametreler. Aslında, bazı diller bunu gerektirir; örneğin, Ada işlevleri
yalnızca mod içi biçimsel parametrelere sahiptir. Bu gereklilik, bir
parametreleri veya takma adları aracılığıyla yan etkilere neden olmaktan
parametreler ve küreseller. Bununla birlikte, diğer zorunlu dillerin çoğunda, işlevler
10. Sözleşme, genel türlerin T'den başlayarak büyük harflerle adlandırıldığını açıkça belirtir.

Sayfa 450
9.10 Fonksiyonlar için Tasarım Konuları 429
ya değere göre ya da referansa göre parametrelere sahip olabilir, böylece
yan etkilere ve örtüşmeye neden olan işlevler.
Haskell gibi saf fonksiyonel dillerin değişkenleri yoktur, bu yüzden onların
fonksiyonların yan etkileri olamaz.
9.10.2 Döndürülen Değer Türleri
Çoğu zorunlu programlama dili, tarafından döndürülebilecek türleri kısıtlar.
onların işlevleri. C, diziler dışında herhangi bir türün işlevleri tarafından döndürülmesine izin verir ve
fonksiyonlar. Bunların her ikisi de işaretçi tipi dönüş değerleri ile işlenebilir. C++ gibidir
C, aynı zamanda kullanıcı tanımlı türlerin veya sınıfların işlevlerinden döndürülmesine de izin verir.
Ada, Python, Ruby ve Lua, mevcut zorunlu diller arasındaki tek dildir.
işlevleri (ve/veya yöntemleri) herhangi bir türden değer döndürebilen göstergeler. durumda
Ancak, Ada'da işlevler tür olmadığı için döndürülemezler.
işlevlerden. Elbette, işlevlere işaretçiler işlevler tarafından döndürülebilir.
Bazı programlama dillerinde alt programlar birinci sınıf nesnelerdir,
bu, işlevlerden döndürülen parametre olarak iletilebilecekleri anlamına gelir,
ve değişkenlere atanır. Yöntemler, bazı zorunlu durumlarda birinci sınıf nesnelerdir.
diller, örneğin Python, Ruby ve Lua. Aynısı işlev için de geçerlidir.
çoğu işlevsel dilde.
Yöntemleri benzer olsa da ne Java ne de C# işlevlere sahip olamaz.
fonksiyonlara. Her ikisinde de, herhangi bir tür veya sınıf, yöntemlerle döndürülebilir. Çünkü
yöntemler tür değildir, döndürülemezler.
9.10.3 Döndürülen Değerlerin Sayısı
Çoğu dilde, bir işlevden yalnızca tek bir değer döndürülebilir. Nasıl-
asla, bu her zaman böyle değildir. Ruby, birden fazla değerin döndürülmesine izin verir
bir yöntemden. Ruby yöntemindeki bir dönüş ifadesinin ardından
bir ifade, nil döndürülür. Bir ifade tarafından takip edilirse, değeri
ifadesi döndürülür. Birden fazla ifade tarafından takip ediliyorsa, bir dizi
tüm ifadelerin değerleri döndürülür.
Lua ayrıca işlevlerin birden çok değer döndürmesine izin verir. Bu tür değerler aşağıdaki
Dönüş virgülle ayrılmış liste olarak aşağıdakilerden olduğu gibi deyimi:
dönüş 3, toplam, dizin
Fonksiyonu çağıran ifadenin formu sayıyı belirler.
arayan tarafından alınan değerlerin. Fonksiyon bir prosedür olarak çağrılırsa,
yani, bir ifade olarak, tüm dönüş değerleri yok sayılır. işlev döndürülürse
üç değer ve tümü arayan tarafından tutulacak, işlev şu şekilde çağrılır:
aşağıdaki örnekte:
a, b, c = eğlence()
F#'ta, bir demete yerleştirilerek birden çok değer döndürülebilir ve
Tuple, işlevdeki son ifade olsun.

Sayfa 451
430
Bölüm 9 Alt Programlar
9.11 Kullanıcı Tanımlı Aşırı Yüklenmiş Operatörler
Operatörler, Ada, C++, Python ve Ruby'de kullanıcı tarafından aşırı yüklenebilir. destek
karmaşık sayıları ve aritmetiği desteklemek için bir Python sınıfının geliştirildiğini varsayalım.
üzerlerinde işlemler. Karmaşık bir sayı iki kayan sayı ile temsil edilebilir.
nokta değerleri. Kompleks sınıf adında bu iki üyeden oluşuyordu
gerçek ve imaj . Python'da ikili aritmetik işlemler şu şekilde uygulanır:
ilk işlenene gönderilen yöntem çağrıları, ikinci işleneni parametre olarak gönderir.
eter. Ek olarak, yöntem __add__ olarak adlandırılır . Örneğin, x ifadesi
+ y , x.__add__(y) olarak uygulanır . Nesnelerin eklenmesi için + aşırı yüklemek için
yeni Complex sınıfından yalnızca Complex ile bir yöntem sağlamamız gerekir.
işlemi gerçekleştiren __add__ adlı . Aşağıdaki böyle bir yöntemdir:
def __add__ (kendi, saniye):
dönüş Karmaşık(self.real + second.real, self.imag +
ikinci.resim)
Nesne yönelimli programlamayı destekleyen çoğu dilde,
geçerli nesne, her yöntem çağrısıyla dolaylı olarak gönderilir. Python'da, bu başvuru-
ence açıkça gönderilmelidir; bu yüzden self ilk parametredir
bizim yöntemimize göre, __add__ .
Örnek ekleme yöntemi, C++'da karmaşık bir sınıf için şu şekilde yazılabilir:
aşağıdaki: 11
Karmaşık operatör +(Karmaşık &saniye) {
dönüş Karmaşık(gerçek + saniye.gerçek, görüntü + saniye.görüntü);
}
9.12 Kapanışlar
Bir kapatmayı tanımlamak basit bir meseledir; bir kapatma bir alt programdır ve ref-
tanımlandığı ortam yaratılır. Referans ortamı
alt program, programdaki herhangi bir rastgele yerden çağrılabilirse gereklidir.
gram. Bir kapanışı açıklamak o kadar basit değil.
Statik kapsamlı bir programlama dili iç içe alt programlara izin vermiyorsa,
gram, kapaklar kullanışlı değildir, bu nedenle bu tür diller onları desteklemez. Hepsi
böyle bir programda bir alt programın referans ortamındaki değişkenler
guage (yerel değişkenleri ve global değişkenleri) ne olursa olsun erişilebilir
programda alt programın çağrıldığı yer.
11. Hem C++ hem de Python karmaşık sayılar için önceden tanımlanmış sınıflara sahiptir, bu nedenle örnek yöntemimiz
ods, çizimler dışında gereksizdir.

Sayfa 452
9.12 Kapanışlar 431
Yerellere ve globallere ek olarak alt programlar yuvalanabildiğinde,
Bir alt programın referans ortamı, tüm programlarda tanımlanan değişkenleri içerebilir.
alt programları içerir. Ancak, alt program kullanılabiliyorsa bu bir sorun değildir.
yalnızca tüm çevreleyen kapsamların etkin ve görünür olduğu yerlerde çağrılır. o
bir alt program başka bir yerde çağrılabilirse sorun olur. Bu, eğer olabilir
alt program bir parametre olarak geçirilebilir veya bir değişkene atanabilir, böylece
programın hemen her yerinden çağrılmasına izin verir. bir
ilişkili sorun: Alt program, bir veya daha fazla işlevinden sonra çağrılabilir.
yuvalama alt programları sona erdi, bu normalde değişkenlerin
bu tür iç içe yerleştirme alt programlarında tanımlananlar serbest bırakıldı - artık
mevcut. Alt programın program içinde herhangi bir yerden çağrılabilir olması için,
referans ortamı, çağrılabilecek her yerde mevcut olmalıdır. Orası-
bu nedenle, yuvalama alt programlarında tanımlanan değişkenler,
sadece alt programın süresinden ziyade tüm programın
tanımlandıkları aktiftir. Ömrü olan bir değişken
tüm programın sınırsız ölçüde olduğu söylenir . Bu genellikle yapmaları gerektiği anlamına gelir
yığın dinamik yerine yığın dinamik olun.
Neredeyse tüm işlevsel programlama dilleri, çoğu betik dili,
ve en az bir öncelikli zorunlu dil olan C#, kapanışları destekler. Bunlar
diller statik kapsamlıdır, iç içe alt programlara izin verir, 12 ve alt programlara izin verir.
gram parametre olarak geçirilir. Aşağıda yazılı bir kapatma örneği verilmiştir
JavaScript'te:
function makeAdder(x) {
dönüş işlevi(y) { dönüş x + y;}
}
. . .
var add10 = makeAdder(10);
var add5 = makeAdder(5);
document.write("10'dan 20'ye ekle: " + add10(20) +
"<br />");
document.write("5'ten 20'ye ekleyin: " + add5(20) +
"<br />");
Bir HTML belgesine gömülü olduğu varsayılarak bu kodun çıktısı
ve bir tarayıcı ile görüntülenen, aşağıdaki gibidir:
10'dan 20'ye ekleyin: 30
5 ila 20 ekleyin: 25
Bu örnekte, kapatma, içinde tanımlanan anonim işlevdir.
makeAdder fonksiyonu makeAdder döner. başvurulan x değişkeni
kapatma işlevinde, makeAdder'a gönderilen parametreye bağlıdır .
12. C#'ta iç içe olabilecek yöntemler yalnızca anonim delegeler ve lambda'dır.
ifade.

Sayfa 453
432
Bölüm 9 Alt Programlar
MakeAdder işlevi kez bir parametre ile iki kez denir 10 ve bir kez
ile 5 . Bu çağrıların her biri, kapatmanın farklı bir sürümünü döndürür, çünkü
farklı x değerlerine bağlıdırlar . makeAdder için yapılan ilk çağrı , bir
parametresine 10 ekleyen fonksiyon ; ikincisi ekleyen bir işlev yaratır
5 kendi parametresine. Fonksiyonun iki versiyonu farklı
makeAdder aktivasyonları . Açıkçası, oluşturulan x sürümünün ömrü
zaman makeAdder programının kullanım boyunca uzanması gereklidir; adlandırılır.
Bu aynı kapatma işlevi, iç içe geçmiş bir anonim kullanılarak C# ile yazılabilir.
temsilci. Yuvalama yönteminin türü, alan bir işlev olarak belirtilir.
parametre olarak bir int ve anonim bir temsilci döndürür. dönüş türü
bu tür delegeler için özel gösterimle belirtilir, Func<int, int> .
Köşeli parantezlerdeki ilk tip parametre tipidir. Böyle bir delege olabilir
Yalnızca bir parametreye sahip yöntemleri kapsülleyin. İkinci tip ise
temsilci tarafından kapsüllenen yöntemin dönüş türü.
statik İşlev< int , int > makeAdder( int x) {
dönüş temsilcisi ( int y) { dönüş x + y;};
}
. . .
Func< int , int > Add10 = makeAdder(10);
Func< int , int > Add5 = makeAdder(5);
Console.WriteLine("10'dan 20'ye Ekle: {0}", Add10(20));
Console.WriteLine("5'ten 20'ye Ekle: {0}", Add5(20));
Bu kodun çıktısı, önceki JavaScript clo- ile tamamen aynıdır.
emin örnek.
İsimsiz delege bir lambda ifadesi olarak yazılabilirdi.
Aşağıdaki, makeAdder yönteminin gövdesinin yerine geçmiştir.
temsilci yerine bir lambda ifadesi:
dönüş y => x + y
Ruby'nin blokları, görünür değişkenlere başvurabilmeleri için uygulanır.
bir yerde çağrılsalar bile tanımlandıkları pozisyonda
hangi değişkenler ortadan kaybolacaktı. Bu, bu tür blokların kapanmasını sağlar.
9.13 Eşyordamlar
Bir eşyordam , özel bir alt program türüdür. Efendi-köleden ziyade
bir arayan ile çağrılan alt program arasındaki ilişki
alt programlar, arayan ve çağrılan eşyordamlar daha eşitlikçidir. Aslında,
eşyordam kontrol mekanizması genellikle simetrik birim kontrol modeli olarak adlandırılır.
Eşyordamlar, aşağıdakiler tarafından kontrol edilen birden fazla giriş noktasına sahip olabilir.
koroutinlerin kendileri. Ayrıca statülerini korumak için araçlara da sahipler.
aktivasyonlar arasında. Bu, eşyordamların tarihe duyarlı olması gerektiği ve

Sayfa 454
9.13 Eşyordamlar 433
bu nedenle statik yerel değişkenlere sahiptir. Bir eşyordamın ikincil uygulamaları genellikle başlar
başlangıcından farklı noktalarda. Bu nedenle, bir eşyordamın çağrılması
çağrı yerine özgeçmiş denir .
Örneğin, aşağıdaki iskelet koroutini düşünün:
alt co1(){
. . .
devam et co2();
. . .
devam et co3();
. . .
}
co1 ilk kez yeniden başlatıldığında, yürütülmesi ilk ifadede başlar
ve kontrolü aktaran CO2'nin özgeçmişine kadar ve buna kadar yürütür
için co2 . CO1'in bir sonraki yeniden başlatılışında, yürütmesi ilk durumda başlar.
co2 çağrısından sonra . Co1 isimli üçüncü kez yeniden, yürütme
co3'ün devam ettirilmesinden sonraki ilk ifadede başlar .
Alt programların olağan özelliklerinden biri eşyordamlarda korunur:
Belirli bir zamanda gerçekte yalnızca bir eşyordam yürütülür.
Yukarıdaki örnekte görüldüğü gibi, bir eşyordamı sonuna kadar yürütmek yerine
genellikle kısmen yürütür ve daha sonra kontrolü başka bir eşyordama aktarır ve
yeniden başlatıldığında, bir eşyordam kullandığı ifadeden hemen sonra yürütmeye devam eder
kontrolü başka bir yere devretmek. Bu tür serpiştirilmiş yürütme dizisi
çoklu programlama işletim sistemlerinin çalışma şekli ile ilgili. orada olmasına rağmen
sadece bir işlemci olabilir, böyle bir sistemdeki tüm çalışan programlar
işlemciyi paylaşırken aynı anda çalışıyor gibi görünüyor. korou durumunda-
dişler, buna bazen yarı eşzamanlılık denir .
Tipik olarak, eşyordamlar, bir uygulamada, adı verilen bir program birimi tarafından oluşturulur.
eşyordam olmayan ana birim. Oluşturulduğunda, eşyordamlar yürütülür
başlatma kodlarını ve ardından kontrolü bu ana birime iade edin. Ne zaman
tüm eşyordamlar ailesi oluşturulur, ana program bunlardan birine devam eder.
eşyordamlar ve eşyordamlar ailesinin üyeleri daha sonra her birine devam eder.
diğerleri, işleri tamamlanıncaya kadar, eğer gerçekten tamamlanabilirse.
Bir eşyordamın yürütülmesi kod bölümünün sonuna ulaşırsa, kontrol
onu oluşturan ana birime aktarılır. Bu, sona erdirme mekanizmasıdır.
arzu edildiğinde, eşyordamların toplanmasının yürütülmesi. bazılarında
programlar, eşyordamlar bilgisayar her çalıştığında çalışır.
Bu tür bir koleksiyonla çözülebilecek bir problem örneği
coroutines bir kart oyunu simülasyonudur. Diyelim ki oyunda dört oyuncu var.
hepsi aynı stratejiyi kullanır. Böyle bir oyun, bir ustaya sahip olunarak simüle edilebilir.
program birimi, her biri bir koleksiyon veya el içeren bir eşyordam ailesi oluşturur.
kartlar. Ana program daha sonra aşağıdakilerden birini sürdürerek simülasyonu başlatabilir.
sırasını oynadıktan sonra bir sonrakine devam edebilecek olan oyuncu eşyordamları
oyuncu eşyordamı ve oyun bitene kadar devam eder.

Sayfa 455
434
Bölüm 9 Alt Programlar
A ve B program birimlerinin eşyordamlar olduğunu varsayalım . Şekil 9.3 iki yolu gösterir
A ve B'yi içeren bir yürütme dizisi devam edebilir.
Şekil 9.3a'da, eşyordam A'nın yürütülmesi ana birim tarafından başlatılır.
Biraz yürütmeden sonra A , B'yi başlatır . Şekil 9.3a'daki eşyordam B ilk neden olduğunda
eşyordam A'ya dönmek için kontrol , anlambilim A'nın devam ettiği yerden devam etmesidir.
son yürütmesini sonlandırdı. Özellikle, yerel değişkenlerinin değerleri kaldı
önceki aktivasyon tarafından. Şekil 9.3b, alternatif bir yürütmeyi gösterir
eşyordam A ve B dizisi . Bu durumda B , ana ünite tarafından başlatılır.
Şekil 9.3'te gösterilen kalıplara sahip olmak yerine, bir eşyordam genellikle
özgeçmiş içeren bir döngü. Şekil 9.4, bunun yürütme sırasını gösterir.
senaryo. Bu durumda A , ana ünite tarafından başlatılır. Ana döngüsünün içinde, A
devam ettirir B , bu da ana döngüsünde A'yı sürdürür .
Çağdaş diller arasında yalnızca Lua eşyordamları tam olarak destekler. 13
13. Bununla birlikte, Python'un oluşturucuları bir tür eşyordamlardır.
Şekil 9.3
İki olası yürütme
için kontrol dizileri
olmadan iki eşyordam
döngüler
A
A'yı devam ettir
A'yı devam ettir
A'yı devam ettir
A'yı devam ettir
B
B
B'ye devam et
B'ye devam et
B'ye devam et
B'ye devam et
B'ye devam et
A
devam et
ustadan
devam et
ustadan
(B)
(a)

Sayfa 456
Özet 435
ÖZET
Süreç soyutlamaları, programlama dillerinde alt programlarla temsil edilir.
gram. Bir alt program tanımı, aşağıdakiler tarafından temsil edilen eylemleri tanımlar.
alt program. Bir alt program çağrısı bu eylemleri gerçekleştirir. Bir alt program başlığı
bir alt program tanımını tanımlar ve adı verilen arayüzünü sağlar.
onun protokolü.
Resmi parametreler, alt programların
alt program çağrılarında verilen gerçek parametreler. Python ve Ruby'de dizi ve
karma biçimsel parametreler, değişken sayıda parametreyi desteklemek için kullanılır.
Lua ve JavaScript ayrıca değişken sayıda parametreyi de destekler. Gerçek para-
eterler, pozisyona veya anahtar kelimeye göre resmi parametrelerle ilişkilendirilebilir.
Parametreler varsayılan değerlere sahip olabilir.
Alt programlar, matematiksel işlevleri modelleyen işlevler olabilir.
tanımlar ve yeni işlemleri veya yeni işlemleri tanımlayan prosedürleri tanımlamak için kullanılır.
ifadeler.
Alt programlardaki yerel değişkenler yığın dinamik olabilir, bu da destek sağlar.
özyineleme için bağlantı noktası veya statik, verimlilik ve geçmişe duyarlı yerel
değişkenler.
JavaScript, Python, Ruby ve Lua, alt program tanımlarının
yuvalanmış.
Parametre geçişinin üç temel anlamsal modeli vardır.
modu, çıkış modu ve giriş modu - ve uygulamaya yönelik bir dizi yaklaşım-
onları. Bunlar, değere göre geçiş, sonuca göre geçiş, değere göre sonuca göre geçiş, geçiş-
referansa göre ve isme göre. Çoğu dilde, parametreler iletilir
çalışma zamanı yığını.
Örtüşme, referanstan geçiş parametreleri kullanıldığında meydana gelebilir, her ikisi de
iki veya daha fazla parametre arasında ve bir parametre ile erişilebilir bir parametre arasında
yerel olmayan değişken.
Şekil 9.4
eşyordam yürütme
döngüler ile dizi
.
.
.
.
.
.
.
.
A'yı devam ettir
.
.
.
B
.
.
.
.
.
.
B'ye devam et
.
.
.
.
.
A
devam et
ustadan
Öncelikle
devam et
Sonraki
devam et

Sayfa 457
436
Bölüm 9 Alt Programlar
Çok boyutlu diziler olan parametreler, lan-
guage tasarımcısı, çünkü çağrılan alt programın nasıl hesaplanacağını bilmesi gerekir.
onlar için depolama eşleme işlevi. Bu sadece isimden fazlasını gerektirir
diziden.
Alt program adları olan parametreler gerekli bir hizmeti sağlar ancak
anlamak zor olabilir. Opaklık, referans ortamında yatar.
parametre olarak geçirilen bir alt program olduğunda kullanılabilir olan ment
Idam edildi.
C ve C++, işlevlere yönelik işaretçileri destekler. C#, delegelere sahiptir.
yöntemlere başvuruları depolayabilen nesneler. Delegeler çok noktaya yayını destekleyebilir
birden fazla yöntem referansı depolayarak çağrılar.
Ada, C++, C#, Ruby ve Python hem alt programa hem de operatöre izin verir
aşırı yükleme. Çeşitli sürümler mümkün olduğu sürece alt programlar aşırı yüklenebilir.
parametrelerinin türleri veya döndürülen değerler tarafından belirsizliği giderilmelidir. İşlev
tanımlar, operatörler için ek anlamlar oluşturmak için kullanılabilir.
C++, Java 5.0 ve C# 2005'teki alt programlar, parametre kullanılarak genel olabilir.
ric polimorfizmi, böylece veri nesnelerinin istenen türleri
daha sonra istenen türler için birimler oluşturabilen derleyici.
Bir dilde bir işlev olanağının tasarımcısı, hangi kısıtlamaların olduğuna karar vermelidir.
döndürülen değerlerin yanı sıra döndürülen değerlerin sayısı üzerine yerleştirilecektir.
Kapanış, bir alt program ve onun referans ortamıdır. Kapanışlar
iç içe alt programlara izin veren, statik kapsamlı olan ve izin veren dillerde kullanışlıdır.
Fonksiyonlardan döndürülecek ve değişkenlere atanacak alt programlar.
Bir eşyordam, birden çok girişi olan özel bir alt programdır. kullanılabilir
alt programların serpiştirilmiş yürütülmesini sağlamak.
İNCELEME SORULARI
1. Alt programların üç genel özelliği nelerdir?
2. Bir alt programın aktif olması ne anlama gelir?
3. Bir alt programın başlığında ne verilir?
4. Python alt programlarının hangi özelliği onları diğerlerinden ayırır?
diğer dillerden?
5. Hangi diller değişken sayıda parametreye izin verir?
6. Ruby dizisi biçimsel parametresi nedir?
7. Parametre profili nedir? Alt program protokolü nedir?
8. Resmi parametreler nelerdir? Gerçek parametreler nelerdir?
9. Anahtar kelime parametrelerinin avantajları ve dezavantajları nelerdir?
10. Bir işlev ve bir prosedür arasındaki farklar nelerdir?
11. Alt programlar için tasarım konuları nelerdir?
12. Dinamik yerel değişkenlerin avantajları ve dezavantajları nelerdir?

Sayfa 458
Soruları gözden geçir 437
13. Statik yerel değişkenlerin avantajları ve dezavantajları nelerdir?
14. Hangi diller alt program tanımlarının iç içe geçmesine izin verir?
15. Parametre geçişinin üç anlamsal modeli nelerdir?
16. Transferin modları, kavramsal modelleri, avantajları,
ve değere göre geçiş, sonuca göre geçiş, değere göre geçiş- dezavantajları
sonuç ve referansa göre parametre geçirme yöntemleri?
17. Geçiş referansı ile takma adların oluşabilme yollarını tanımlayın
parametreler.
18. Orijinal C ve C89'un bir
tipi karşılık gelen ile aynı olmayan gerçek parametre
biçimsel parametre?
19. Parametre geçişi için iki temel tasarım düşüncesi nelerdir?
yöntemler?
20. Çok boyutlu dizileri parametre olarak geçirme problemini tanımlayın.
21. Ruby'de kullanılan parametre geçiş yönteminin adı nedir?
22. Alt program adları değiştirildiğinde ortaya çıkan iki sorun nelerdir?
parametreler?
23. Alt programların referans ortamları için sığ ve derin ciltlemeyi tanımlayın .
parametre olarak geçirilen gramlar.
24. Aşırı yüklenmiş bir alt program nedir?
25. Parametrik polimorfizm nedir?
26. Bir C++ şablon işlevinin somutlaştırılmasına neden olan nedir?
27. Genel parametreler bir Java 5.0 için hangi temel yollarla yapılır?
genel yöntem, C++ yöntemlerinden farklı mı?
28. Bir Java 5.0 yöntemi genel bir tür döndürürse, gerçekte ne tür bir nesnedir?
iade?
29. Bir Java 5.0 jenerik yöntemi üç farklı jenerik ile çağrılırsa
parametreleri, yöntemin kaç versiyonunun oluşturulacağını
derleyici?
30. Fonksiyonlar için tasarım konuları nelerdir?
31. Hangi iki dil, bir dilden birden çok değer döndürülmesine izin verir?
işlev?
32. Delege tam olarak nedir?
33. F#'daki genel işlevlerin ana dezavantajı nedir?
34. Kapatma nedir?
35. Kapanışları faydalı kılan dil özellikleri nelerdir?
36. Hangi diller kullanıcının operatörleri aşırı yüklemesine izin verir?
37. Eşyordamlar hangi yönlerden geleneksel alt programlardan farklıdır?

Sayfa 459
438
Bölüm 9 Alt Programlar
PROBLEM SETİ
1. Bir kullanıcı programı için ek oluşturma lehinde ve aleyhindeki argümanlar nelerdir?
Python ve C++'da yapılabileceği gibi mevcut operatörler için tanımlar? Yapmak
bu tür kullanıcı tanımlı operatör aşırı yüklemesinin iyi mi kötü mü olduğunu düşünüyorsunuz? destek
cevabınızı aktarın.
2. Çoğu Fortran IV uygulamasında, parametreler referansla geçirilmiştir.
ence, yalnızca erişim yolu iletimini kullanarak. Hem avantajlarını hem de
bu tasarım seçiminin dezavantajları.
3. Ada 83 tasarımcılarının uygulamaya izin verme kararını desteklemek için tartışın.
inout -mode parametrelerinin uygulanması arasında seçim yapmak için mentor
kopyalayın veya referans olarak.
4. Yeni bir çıktıya bir başlık yazdıran bir yöntem yazmak istediğinizi varsayalım.
ilk aktivasyonda 1 olan bir sayfa numarası ile birlikte sayfa koyun ve
bu, sonraki her aktivasyonda 1 artar. bu yapılabilir mi
Java'da parametresiz ve yerel olmayan değişkenlere başvurmadan?
C# ile yapılabilir mi?
5. C sözdiziminde yazılmış aşağıdaki programı göz önünde bulundurun:
geçersiz takas( int a, int b) {
int sıcaklık;
sıcaklık = bir;
a = b;
b = sıcaklık;
}
geçersiz ana() {
int değeri = 2, liste[5] = {1, 3, 5, 7, 9};
takas(değer, liste[0]);
takas(liste[0], liste[1]);
takas(değer, liste[değer]);
}
Aşağıdaki parametre geçirme yöntemlerinin her biri için, aşağıdakilerin tümü nedir?
üç çağrının her birinden sonra değişkenlerin değerleri ve listesi
takas ?
a. değere göre geçti
B. referans ile geçti
C. değer-sonuç tarafından geçti
6. Hem statik hem de dinamik yerel sağlamaya karşı bir argüman sunun
Alt programlardaki değişkenler.
7. C sözdiziminde yazılmış aşağıdaki programı göz önünde bulundurun:
void fun ( int birinci, int ikinci) {
ilk += ilk;

Sayfa 460
Programlama Alıştırmaları 439
saniye += saniye;
}
geçersiz ana() {
int liste[2] = {1, 3};
fun(list[0], liste[1]);
}
Aşağıdaki parametre geçirme yöntemlerinin her biri için değer nedir?
erlerini listesi yürütme sonrası dizi?
a. değere göre geçti
B. referans ile geçti
C. değer-sonuç tarafından geçti
8. Yalnızca işlev alt programları sağlayan C tasarımına karşı çıkın.
9. Fortran'daki bir ders kitabından, deyimin sözdizimini ve anlamını öğrenin
fonksiyonlar. Fortran'daki varlıklarını gerekçelendirin.
10. C++ ve Ada'da kullanıcı tanımlı operatör aşırı yükleme yöntemlerini inceleyin,
ve değerlendirme kriterlerimizi kullanarak ikisini karşılaştıran bir rapor yazın
Diller.
11. C#, mod dışı parametreleri destekler, ancak ne Java ne de C++ desteklemez.
Farkı açıklayın.
12. Yansıtmanın yaygın olarak bilinen bir kullanımı olan Jensen Aygıtını araştırın.
parametreleri adlandırın ve ne olduğu ve nasıl olduğu hakkında kısa bir açıklama yazın
kullanılabilir.
13. Ruby ve CLU'nun yineleyici mekanizmalarını inceleyin ve benzerliklerini listeleyin.
bağlar ve farklılıklar.
14. Programlamada iç içe alt programlara izin verilmesi konusunda spekülasyon yapın
diller—neden birçok çağdaş dilde bunlara izin verilmiyor?
15. İsme göre geçiş kullanımına karşı en az iki argüman nelerdir?
parametreler?
16. Java 5.0'ın genel alt programlarının ayrıntılı bir karşılaştırmasını yazın ve
C# 2005.
PROGRAMLAMAALIŞTIRMALAR
1. Oranını belirlemek için bildiğiniz bir dilde bir program yazın.
başvuruya göre büyük bir diziyi geçmek için gereken süre ve gereken süre
aynı diziyi değere göre geçirmek için. Diziyi mümkün olduğunca büyük yapın
kullandığınız makine ve uygulama. Diziyi birçok kez iletin
geçen işlemlerin makul ölçüde doğru zamanlamasını elde etmek için gerektiği gibi.
2. Bir çıkışın adresinin ne zaman geleceğini belirleyen bir C# veya Ada programı yazın.
mode parametresi hesaplanır (çağrı sırasında veya yürütme sırasında).
alt programın bitişi).

Sayfa 461
440
Bölüm 9 Alt Programlar
3. Değişmezi referans alarak bir alt programa aktaran bir Perl programı yazın,
parametreyi değiştirmeye çalışır. Genel tasarım kalitesi göz önüne alındığında
Perl felsefesi, sonuçları açıklayınız.
4. Programlama Alıştırması 3'ü C# ile tekrarlayın.
5. Hem statik hem de yığın içeren bir dilde bir program yazın.
alt programlarda dinamik yerel değişkenler. Altı büyük oluşturun (en az
100 * 100) alt programdaki matrisler—üç statik ve üç yığın
dinamik. Statik matrislerden ikisini ve yığın dinamiklerinden ikisini doldurun
1 ile 100 arasında rastgele sayılar içeren matrisler.
alt program çok sayıda matris çarpma işlemi gerçekleştirmelidir.
statik matrisler ve süreci zamanlama üzerine açıklamalar. O zaman tekrar etmeli
bu yığın dinamik matrislerle. Sonuçları karşılaştırın ve açıklayın.
6. Büyük olarak adlandırılan iki yöntemi içeren bir C# programı yazın.
defalarca. Her iki yöntem de değere göre büyük bir diziden geçirilir
ve referans olarak bir. Bu ikisini aramak için gereken süreleri karşılaştırın
yöntemleri ve farkı açıklar. Onları yeterli olarak adlandırdığınızdan emin olun.
gerekli süredeki bir farkı göstermek için kaç kez.
7. İstediğiniz dilin sözdizimini kullanarak bir program yazın.
referansa veya referansa bağlı olarak farklı davranışlar üretir.
parametre geçişinde değere göre sonuç kullanılır.
8. Bir dizi genel öğe alan genel bir Ada işlevi yazın ve
dizi öğeleriyle aynı türden bir skaler. dizinin türü ele-
ments ve skaler genel parametredir. Dizinin abonelikleri
pozitif tam sayılardır. İşlev, verilen diziyi aşağıdakiler için aramalıdır:
verilen skaler ve dizideki skalerin alt indisini döndürür. eğer ske-
lar dizide değilse, işlev –1 döndürmelidir . Fonksiyonu somutlaştır-
Tamsayı ve Float türleri için tion ve her ikisini de test edin.
9. Bir dizi genel öğe alan ve genel bir C++ işlevi yazın.
dizi öğeleriyle aynı türden bir skaler. dizinin türü ele-
ments ve skaler genel parametredir. İşlev aramalı
verilen skaler için verilen dizi ve skalerin alt indisini döndür
dizide. Skaler dizide değilse, işlev –1 döndürmelidir .
İşlevi int ve float türleri için test edin .
10. Bir alt program ve bir arama kodu tasarlayın.
bir veya daha fazla parametrenin değer-sonucu farklı üretir
Sonuçlar.

Sayfa 462
441
10.1 Çağrıların ve İadelerin Genel Anlamı
10.2 “Basit” Alt Programların Uygulanması
10.3 Stack-Dynamic ile Alt Programları Uygulamak
Yerel Değişkenler
10.4 İç İçe Alt Programlar
10.5 Blok
10.6 Dinamik Kapsam Belirleme Uygulaması
10
uygulama
alt programlar

Sayfa 463
442
Bölüm 10 Alt Programları Uygulamak
T Bu bölümün o amaç alt programların uygulanmasını keşfetmektir.
Tartışma, okuyucuya alt pro-
gram bağlantısı çalışır ve ayrıca ALGOL 60'ın neden belirsizliğe meydan okuduğunu
1960'ların başındaki derleyici yazarları bekliyor. En basit durumla başlıyoruz,
Statik yerel değişkenlere sahip, sabit olmayan alt programlar, daha karmaşık hale gelir
yığın dinamik yerel değişkenlere sahip alt programlar ve iç içe alt programlarla sonuçlandırma
yığın dinamik yerel değişkenler ve statik kapsam ile gram. Artan zorluk
Alt programların iç içe geçmiş alt programlara sahip dillerde uygulanmasının nedeni,
yerel olmayan değişkenlere erişmek için mekanizmalar içerme ihtiyacı.
Statik kapsamlı dillerde yerel olmayanlara erişmenin statik zincir yöntemi
ayrıntılı olarak tartışıldı. Ardından, blokları uygulama teknikleri açıklanır. Nihayet,
dinamik kapsamlı bir alanda yerel olmayan değişken erişimini uygulamaya yönelik çeşitli yöntemler
guaj tartışılır.
10.1 Çağrıların ve İadelerin Genel Anlamı
Alt program çağırma ve geri döndürme işlemleri birlikte alt program olarak adlandırılır.
bağı . Alt programların uygulanması anlambilime dayalı olmalıdır.
uygulanan dilin alt program bağlantısının
Tipik bir dilde bir alt program çağrısı, çok sayıda eylem ilişkisine sahiptir.
onunla yedi. Çağrı süreci, ne olursa olsun uygulanmasını içermelidir.
parametre geçirme yöntemi kullanılır. Yerel değişkenler statik değilse, çağrı
süreç, çağrılan alt programda bildirilen yereller için depolama tahsis etmelidir.
ve bu değişkenleri o depoya bağlayın. Yürütme durumunu kaydetmeli
çağıran program biriminin Yürütme durumu için gereken her şey
çağıran program biriminin yürütülmesine devam edin. Buna kayıt değerleri dahildir,
CPU durum bitleri ve ortam işaretçisi (EP). EP, daha ileri
Bölüm 10.3'te tartışılan, parametrelere ve yerel değişkenlere erişmek için kullanılır
Bir alt programın yürütülmesi sırasında. Çağırma süreci de düzenlemelidir
kontrolü alt programın koduna aktarmak ve kontrolü sağlamak
alt program yürütmesi tamamlandığında uygun yere dönebilir.
Son olarak, dil iç içe alt programları destekliyorsa, çağrı işlemi
görünür olan yerel olmayan değişkenlere erişim sağlamak için bazı mekanizmalar oluşturun
çağrılan alt programa
Bir alt program dönüşünün gerekli eylemleri, aşağıdakilerden daha az karmaşıktır.
bir çağrı olanlar. Alt programda çıkış modu veya giriş çıkışı olan parametreler varsa
modunda ve kopya ile uygulanır, iade işleminin ilk eylemi
ilgili resmi parametrelerin yerel değerlerini gerçek parametreye taşıyın.
ters. Ardından, yerel değişkenler için kullanılan depolamayı serbest bırakmalı ve
çağıran program biriminin yürütme durumu. Son olarak, kontrol iade edilmelidir
çağıran program birimine

Sayfa 464
10.2 “Basit” Alt Programların Uygulanması 443
10.2 “Basit” Alt Programların Uygulanması
Basit alt programları uygulama göreviyle başlıyoruz. "Basit" derken
alt programların yuvalanamayacağı ve tüm yerel değişkenlerin statik olduğu anlamına gelir. Erken
Fortran sürümleri bu tür alt programlara sahip dillerin örnekleriydi.
"Basit" bir alt programa yapılan bir çağrının anlamı aşağıdakileri gerektirir:
hareketler:
1. Geçerli program biriminin yürütme durumunu kaydedin.
2. Parametreleri hesaplayın ve iletin.
3. Aranan kişiye dönüş adresini iletin.
4. Kontrolü aranan kişiye aktarın.
Basit bir alt programdan dönüşün anlamı aşağıdakileri gerektirir:
eylemler:
1. Değere göre geçiş sonucu veya mod dışı parametreler varsa, mevcut
bu parametrelerin değerleri ilgili bölüme taşınır veya kullanıma sunulur.
gerçek parametreleri yanıtlama.
2. Alt program bir fonksiyon ise, fonksiyonel değer bir yere taşınır.
arayan kişi tarafından erişilebilir.
3. Arayanın yürütme durumu geri yüklenir.
4. Kontrol, arayan kişiye geri aktarılır.
Arama ve geri gönderme eylemleri, aşağıdakiler için depolama gerektirir:
• Arayan hakkında durum bilgisi
• Parametreler
• İade adresi
• Fonksiyonlar için dönüş değeri
• Alt programların kodu tarafından kullanılan geçiciler
Bunlar, yerel değişkenler ve alt program kodu ile birlikte,
Bir alt programın yürütmesi ve ardından geri dönmesi gereken bilgilerin eksiksiz bir şekilde toplanması
arayana kontrol.
Şimdi soru, çağrı ve geri dönüş eylemlerinin dağıtılmasıdır.
arayan ve aranan. Basit alt programlar için cevap çoğu için açıktır.
sürecin bölümlerinden biridir. Bir aramanın son üç eylemi açıkça yapılmalıdır
arayan tarafından. Arayanın yürütme durumunun kaydedilmesi ikisinden biri ile yapılabilir.
İade durumunda, birinci, üçüncü ve dördüncü işlemler tarafından yapılmalıdır.
denilen. Bir kez daha, arayanın yürütme durumunun geri yüklenmesi,
arayan veya aranan tarafından yapılmalıdır. Genel olarak, bağlantı eylemleri
çağrılması, yürütmenin başlangıcında olmak üzere iki farklı zamanda ortaya çıkabilir.
veya sonunda. Bunlara bazen alt bölümün önsözü ve son sözü denir.
program bağlantısı. Basit bir alt program durumunda, tüm bağlantı eylemleri
aranan kişinin icrasının sonunda meydana gelir, bu nedenle bir ön söze gerek yoktur.

Sayfa 465
444
Bölüm 10 Alt Programları Uygulamak
Basit bir alt program iki ayrı bölümden oluşur: programın gerçek kodu.
sabit olan alt program ve önceden listelenen yerel değişkenler ve veriler
alt program yürütüldüğünde değişebilir. basit durumda
alt programlar, bu parçaların her ikisi de sabit boyutlara sahiptir.
Bir alt programın kod olmayan bölümünün formatına veya düzenine bir program adı verilir.
aktivasyon kaydı , çünkü açıkladığı veriler yalnızca işlem sırasında alakalıdır .
alt programın etkinleştirilmesi veya yürütülmesi. Aktivasyon kaydı formu
statiktir. Bir aktivasyon kaydı, örneğin , bir aktivasyon somut örneği
kayıt, bir etkinleştirme kaydı biçiminde bir veri koleksiyonu.
Basit alt programlara sahip diller özyinelemeyi desteklemediğinden,
aynı anda belirli bir alt programın yalnızca bir aktif versiyonu olabilir. Öyleyse,
bir alt program için aktivasyon kaydının yalnızca tek bir örneği olabilir.
Aktivasyon kayıtları için olası bir düzen Şekil 10.1'de gösterilmektedir. kaydedilen
arayanın yürütme durumu burada ve bu bölümün geri kalanında atlanmıştır.
ter çünkü basit ve tartışmayla ilgili değil.
Çünkü "basit" bir alt program için bir aktivasyon kaydı örneği düzeltildi.
boyut, statik olarak tahsis edilebilir. Aslında, kod kısmına eklenebilir.
alt programın
Şekil 10.2, bir ana program ve üç programdan oluşan bir programı göstermektedir.
alt programlar: A , B ve C . Şekil tüm kod bölümlerini gösterse de
tüm aktivasyon kaydı örneklerinden ayrılmış, bazı durumlarda aktivasyon
kayıt örnekleri, ilişkili kod bölümlerine eklenir.
Şekil 10.2'de gösterilen programın tamamı yapılmamıştır.
tamamen derleyici tarafından. Aslında, eğer dil bağımsız derlemeye izin veriyorsa,
dört program birimi — MAIN , A , B ve C — farklı programlarda derlenmiş olabilir.
günlerde, hatta farklı yıllarda. Her birim derlendiğinde, makine
bunun için kod, harici alt programlara yapılan referansların bir listesi ile birlikte bir
dosya. Şekil 10.2'de gösterilen yürütülebilir program, linker tarafından bir araya getirilir ,
hangi işletim sisteminin bir parçasıdır. (Bazen bağlayıcılara yükleyici, bağlayıcı/
yükleyiciler veya bağlantı düzenleyiciler .) Bağlayıcı bir ana program için çağrıldığında, ilk görevi
o programda atıfta bulunulan çevrilmiş alt programları içeren dosyaları bulmaktır.
gram ve bunları belleğe yükleyin. Ardından, bağlayıcı hedef adresleri belirlemelidir.
ana programdaki bu alt programlara yapılan tüm çağrıların giriş adreslerine
bu alt programlar. Aynısı, alt programlara yapılan tüm çağrılar için yapılmalıdır.
yüklenen alt programlar ve kitaplık alt programlarına yapılan tüm çağrılar. Önceki örnekte,
bağlayıcı MAIN için çağrıldı . Bağlayıcı, makine kodu programlarını bulmak zorundaydı
için bir , B , ve C , bunların aktivasyon kaydı kopyaları ile birlikte, ve onlara yük
Şekil 10.1
için bir aktivasyon kaydı
basit alt programlar
İade adresi
parametreler
yerel değişkenler

Sayfa 466
10.3 Yığın Dinamik Yerel Değişkenlerle Alt Programları Uygulama 445
MAIN kodunu içeren hafıza . Ardından, hedef adreslerde yama yapmak zorunda kaldı.
A , B , C ve A , B , C ve MAIN içindeki herhangi bir kitaplık alt programlarına yapılan tüm çağrılar .
10.3 Stack-Dynami c ile Alt Programları Uygulamak
Yerel Değişkenler
Şimdi, dillerde alt program bağlantısının uygulanmasını inceliyoruz.
hangi yereller yığın dinamiktir, yine arama ve geri dönüş işlemlerine odaklanır.
Yığın dinamik yerel değişkenlerin en önemli avantajlarından biri
özyineleme desteğidir. Bu nedenle, yığın dinamik yerel kullanan diller
değişkenler de özyinelemeyi destekler.
Alt programlar mümkün olduğunda gerekli olan ek karmaşıklığın tartışılması
yuvalanma, Bölüm 10.4'e ertelendi.
10.3.1 Daha Karmaşık Aktivasyon Kayıtları
Yığın dinamik yerel değişkenleri kullanan dillerde alt program bağlantısı
aşağıdaki nedenlerle basit alt programların bağlantısından daha karmaşıktır:
• Derleyici, örtülü tahsise ve anlaşmaya neden olmak için kod üretmelidir.
yerel değişkenlerin konumu.
Şekil 10.2
kod ve
aktivasyon kayıtları
basit bir program
alt programlar
ANA
Veri
kod
A
B
C
ANA
A
B
C
yerel değişkenler
yerel değişkenler
parametreler
İade adresi
yerel değişkenler
parametreler
İade adresi
yerel değişkenler
parametreler
İade adresi

Sayfa 467
446
Bölüm 10 Alt Programları Uygulamak
• Özyineleme, bir alt öğenin aynı anda birden çok etkinleştirilmesi olasılığını ekler.
program, bu, birden fazla örnek olabileceği anlamına gelir (gelen
en az bir çağrı ile belirli bir zamanda bir alt programın tam yürütmesi)
alt programın dışında ve bir veya daha fazla özyinelemeli çağrı. Sayısı
etkinleştirmeler yalnızca makinenin bellek boyutuyla sınırlıdır. Her aktif-
tion, aktivasyon kaydı örneğini gerektirir.
Çoğu programda belirli bir alt program için aktivasyon kaydının formatı.
guages ​​derleme zamanında bilinir. Çoğu durumda, boyut da bilinir
etkinleştirme kayıtları, çünkü tüm yerel veriler sabit bir boyuttadır. durum böyle değil
Yerel bir dizinin boyutunun kullanılabildiği Ada gibi diğer bazı dillerde
gerçek bir parametrenin değerine bağlıdır. Bu durumlarda, biçim statiktir,
ancak boyut dinamik olabilir. Yığın dinamik yerel değişkenleri olan dillerde,
aktivasyon kaydı örnekleri dinamik olarak oluşturulmalıdır. Tipik aktivasyon
böyle bir dil için kayıt Şekil 10.3'te gösterilmiştir.
Dönüş adresi, dinamik bağlantı ve parametreler
arayan tarafından aktivasyon kaydı örneği, bu girişler önce görünmelidir.
Şekil 10.3
Tipik bir aktivasyon
bir dil için kayıt
yığın dinamikli
yerel değişkenler
Dinamik bağlantı
İade adresi
parametreler
yerel değişkenler
Yığın üstü
İade adresi genellikle aşağıdaki talimata yönelik bir işaretçiden oluşur.
arayan program biriminin kod bölümündeki arama. Dinamik bağlantı olduğunu
arayanın aktivasyon kaydı örneğinin tabanına bir işaretçi. statik olarak
Kapsamlı diller, bu bağlantı, bir
çalışma zamanı hatası oluşur. Dinamik kapsamlı dillerde dinamik bağlantı kullanılır
yerel olmayan değişkenlere erişmek için. Aktivasyon kaydındaki gerçek parametreler şunlardır:
arayan tarafından sağlanan değerler veya adresler.
Yerel skaler değişkenler, bir etkinleştirme kaydı içindeki depolamaya bağlıdır
misal. Yapı olan yerel değişkenler bazen başka yerlere tahsis edilir,
ve yalnızca tanımlayıcıları ve bu depolamaya yönelik bir işaretçi, etkinleştirmenin bir parçasıdır.
kayıt kaydı. Yerel değişkenler atanır ve muhtemelen çağrılan dosyada başlatılır.
alt program, böylece en son görünürler.
Aşağıdaki iskelet C fonksiyonunu göz önünde bulundurun:
void sub( şamandıra toplam, int kısım) {
int listesi[5];
kayan toplam;
. . .
}
Sub için aktivasyon kaydı Şekil 10.4'te gösterilmiştir.

Sayfa 468
10.3 Yığın Dinamik Yerel Değişkenlerle Alt Programları Uygulama 447
Bir alt programı etkinleştirmek, bir örneğinin dinamik olarak oluşturulmasını gerektirir.
alt program için aktivasyon kaydı. Daha önce de belirtildiği gibi, format
aktivasyon kaydı derleme zamanında sabitlenir, ancak boyutu buna bağlı olabilir.
arama bazı dillerde. Çünkü çağrı ve dönüş semantiği şunu belirtir:
son çağrılan alt program ilk tamamlanan programdır, oluşturulması mantıklıdır.
bir yığında bu aktivasyon kayıtlarının örnekleri. Bu yığın, çalışmanın bir parçasıdır-
zaman sistemidir ve bu nedenle çalışma zamanı yığını olarak adlandırılır , ancak
müttefik sadece yığın olarak bakın. Özyinelemeli olsun, her alt program aktivasyonu
veya özyinelemeli olmayan, yığında bir etkinleştirme kaydının yeni bir örneğini oluşturur.
Bu, parametrelerin gerekli ayrı kopyalarını, yerel değişkenleri,
ve dönüş adresi.
Bir alt programın yürütülmesini kontrol etmek için bir şey daha gereklidir -
EP. Başlangıçta, EP tabanı veya aktivasyonun ilk adresini gösterir.
ana programın örneğini kaydedin. Bu nedenle, çalışma zamanı sistemi
her zaman aktivasyon kaydı örneğinin tabanına işaret ettiğinden emin olun.
Şu anda yürütülmekte olan program birimi. Bir alt program çağrıldığında,
mevcut EP, yeni aktivasyon kaydı örneğinde dinamik olarak kaydedilir.
bağlantı. EP daha sonra yeni aktivasyon kaydının tabanını gösterecek şekilde ayarlanır.
misal. Alt programdan döndükten sonra, yığın üstü değere ayarlanır.
mevcut EP'nin eksi bir ve EP, dinamik bağlantıya ayarlanır.
Yürütülmesini tamamlayan alt programın aktivasyon kaydı örneği
tion. Yığın tepesini sıfırlamak, üst etkinleştirme kaydını etkin bir şekilde kaldırır
misal.
Şekil 10.4
aktivasyon kaydı
fonksiyon alt için
Yerel
Yerel
Yerel
Yerel
Parametre
Parametre
Dinamik bağlantı
İade adresi
Yerel
Yerel
liste [3]
liste [2]
liste [1]
liste [0]
Bölüm
Toplam
liste [4]
toplam

Sayfa 469
448
Bölüm 10 Alt Programları Uygulamak
EP, veri içeriğinin ofset adreslemesinin temeli olarak kullanılır.
etkinleştirme kaydı örneği—parametreler ve yerel değişkenler.
Şu anda kullanılmakta olan EP'nin çalışma zamanı yığınında saklanmadığını unutmayın.
Etkinleştirme kaydı örneklerinde yalnızca kaydedilen sürümler dinamik olarak saklanır.
bağlantılar.
Şimdi bağlantı sürecindeki birkaç yeni eylemi tartıştık.
Bölüm 10.2'de verilen listeler, bunları dikkate alacak şekilde revize edilmelidir.
Bu bölümde verilen aktivasyon kayıt formu kullanılarak yeni aksiyonlar
aşağıdaki gibi:
Arayan eylemleri aşağıdaki gibidir:
1. Bir etkinleştirme kaydı örneği oluşturun.
2. Mevcut program biriminin yürütme durumunu kaydedin.
3. Parametreleri hesaplayın ve iletin.
4. Aranan kişiye dönüş adresini iletin.
5. Kontrolü aranan kişiye aktarın.
Çağrılanların prolog eylemleri aşağıdaki gibidir:
1. Yığındaki eski EP'yi dinamik bağlantı olarak kaydedin ve yeni EP'yi oluşturun.
değer.
2. Yerel değişkenleri tahsis edin.
Çağrılanların sonsöz eylemleri aşağıdaki gibidir:
1. Değere göre geçiş sonucu veya mod dışı parametreler varsa, akım-
bu parametrelerin kira değerleri karşılık gelen gerçek değerlere taşınır.
parametreler.
2. Alt program bir fonksiyon ise, fonksiyonel değer bir yere taşınır.
arayan kişi tarafından erişilebilir.
3. Mevcut EP'nin değerine ayarlayarak yığın işaretçisini geri yükleyin.
eksi bir ve EP'yi eski dinamik bağlantıya ayarlayın.
4. Arayanın yürütme durumunu geri yükleyin.
5. Kontrolü arayana geri aktarın.
Bölüm 9'dan bir alt programın başlatıldığı andan itibaren aktif olduğunu hatırlayın.
yürütme tamamlanana kadar çağrılır. O zaman etkisiz hale gelir-
yerel kapsamı sona erer ve referans ortamı eskimez.
gerce anlamlı. Bu nedenle, o sırada, aktivasyon kaydı örneği şu şekilde olabilir:
yerlebir edilmiş.
Parametreler her zaman yığında aktarılmaz. Birçok derleyicide
RISC makineleri için parametreler kayıtlardan geçirilir. Bunun nedeni RISC'nin
makinelerin normalde CISC makinelerinden çok daha fazla kaydı vardır. İçinde
Bununla birlikte, bu bölümün geri kalanında, parametrelerin iletildiğini varsayıyoruz.

Sayfa 470
10.3 Yığın Dinamik Yerel Değişkenlerle Alt Programları Uygulama 449
yığın. Parametreler için bu yaklaşımı değiştirmek kolaydır.
kayıtlarda geçti.
10.3.2 Özyinelemesiz Bir Örnek
Aşağıdaki iskelet C programını göz önünde bulundurun:
void fun1( float r) {
int s, t;
. . .
1
eğlence2(ler);
. . .
}
void fun2( int x) {
int y;
. . .
2
eğlence3(y);
. . .
}
void fun3( int q) {
. . .
3
}
geçersiz ana() {
yüzer p;
. . .
eğlence1(p);
. . .
}
Bu programdaki fonksiyon çağrılarının sırası
ana çağrılar fun1
fun1 fun2'yi çağırır
fun2 fun3'ü çağırır
1, 2 ve 3 olarak etiketlenen noktalar için yığın içeriği
Şekil 10.5.
1. noktada, yalnızca ana işlev için etkinleştirme kaydı örnekleri ve
fun1 işlevi yığındadır . Tüm fun1 aramaları FUN2 , bir örneğini FUN2 s’
yığın üzerinde aktivasyon kaydı oluşturulur. FUN2 çağıran fun3 , bir örnek
stack üzerinde fun3 aktivasyon kaydı oluşturulur. Tüm fun3 ‘in yürütülmesi
biter, aktivasyon kaydının örneği yığından kaldırılır ve
EP, yığın üst işaretçisini sıfırlamak için kullanılır. Benzer süreçler ne zaman gerçekleşir

Sayfa 471
450
Bölüm 10 Alt Programları Uygulamak
fonksiyonları FUN2 ve fun1 sonlandırabilir. Çağrıdan fun1'e döndükten sonra
gelen ana yığın aktivasyonu kaydının sadece örneği vardır ana .
Bazı uygulamaların aslında bir etkinleştirme kaydı kullanmadığını unutmayın.
şekilde gösterilen gibi ana işlevler için yığındaki örnek.
Ancak bu şekilde yapılabilir ve hem uygulamayı kolaylaştırır.
ve tartışmamız. Bu örnekte ve bu bölümdeki diğer tüm örneklerde,
yığının daha düşük adreslerden daha yüksek adreslere doğru büyüdüğünü varsayıyoruz,
belirli bir uygulamada, yığın tam tersine büyüyebilir
yön.
Belirli bir zamanda yığında bulunan dinamik bağlantıların koleksiyonu
denilen dinamik zincir veya çağrı zinciri . dinamik tarihini temsil eder.
yürütme, her zaman alt programda olan mevcut konumuna nasıl geldi?
aktivasyon kaydı örneği yığının üstünde olan kod. yerel referanslar
değişkenler, kodda başlangıcından itibaren ofsetler olarak temsil edilebilir.
adresi EP'de saklanan yerel kapsamın etkinleştirme kaydı. Bu tür bir
offset, local_offset olarak adlandırılır .
Aktivasyon kaydındaki bir değişkenin local_offset'i belirlenebilir
derleme zamanında, belirtilen değişkenlerin sırasını, türlerini ve boyutlarını kullanarak
aktivasyon kaydıyla ilişkili alt program. Tartışmayı basitleştirmek için,
Şekil 10.5
Bir programda üç nokta için yığın içeriği
Tepe
Yerel
Yerel
Parametre
Dinamik bağlantı
Ana sayfaya DÖN)
Yerel
1. noktada
2. noktada
3. noktada
ARI
ana için
T
s
r
Yerel
Parametre
Dinamik bağlantı
(eğlence1'e dön)
Yerel
Yerel
Parametre
Dinamik bağlantı
Yerel
Ana sayfaya DÖN)
ARI
ana için
Tepe
T
s
y
x
r
P
Yerel
Parametre
Dinamik bağlantı
Yerel
Yerel
Parametre
Dinamik bağlantı
Yerel
Ana sayfaya DÖN)
ARI
ana için
Tepe
T
s
y
Q
x
r
P
Parametre
Dinamik bağlantı
(eğlence2'ye dön)
ARI = aktivasyon kaydı örneği
ARI
eğlence için1
ARI
eğlence için1
ARI
eğlence için2
ARI
eğlence için3
ARI
eğlence için2
ARI
eğlence için1
(eğlence1'e dön)
P

Sayfa 472
10.3 Yığın Dinamik Yerel Değişkenlerle Alt Programları Uygulama 451
tüm değişkenlerin aktivasyon kaydında bir pozisyon aldığını varsayıyoruz. bu
bir alt programda bildirilen ilk yerel değişken, aktivasyonda tahsis edilecektir.
iki konum artı alttan parametre sayısını kaydedin
(ilk iki konum dönüş adresi ve dinamik bağlantı içindir). bu
Bildirilen ikinci yerel değişken, yığının tepesine yakın bir konum olacaktır ve
saire. Örneğin, önceki örnek programı düşünün. In FUN1 ,
arasında local_offset s , 3'tür; için t içeri Benzer şekilde, 4'tür FUN2 ait local_offset y
3'tür. Herhangi bir yerel değişkenin adresini almak için, değişkenin local_offset değeri
EP'ye eklendi.
10.3.3 Özyineleme
Hesaplamak için özyinelemeyi kullanan aşağıdaki örnek C programını göz önünde bulundurun.
faktöriyel fonksiyon:
int faktöriyel( int n) {
1
eğer (n <= 1)
dönüş 1;
başka bir dönüş (n * faktöriyel(n - 1));
2
}
geçersiz ana() {
int değeri;
değer = faktöriyel(3);
3
}
Faktöriyel fonksiyon için aktivasyon kayıt formatı Şekil 10.6'da gösterilmektedir.
İşlevin dönüş değeri için ek bir girişi olduğuna dikkat edin.
Şekil 10.7, üç kez yürütme için yığının içeriğini gösterir.
fonksiyon faktöriyelinde konum 1'e ulaşır . Her biri bir tane daha gösteriyor
Fonksiyonel değeri tanımsız olarak fonksiyonun aktivasyonu. İlk
aktivasyon kaydı örneği, çağıran fonksiyona dönüş adresine sahiptir,
Şekil 10.6
aktivasyon kaydı
faktöriyel için
Dinamik bağlantı
İade adresi
Parametre
fonksiyonel değer
n

Sayfa 473
452
Bölüm 10 Alt Programları Uygulamak
ana . Diğerlerinin işlevin kendisine bir dönüş adresi vardır; bunlar için
özyinelemeli çağrılar.
Şekil 10.8, yürütmenin üç katı için yığın içeriğini gösterir.
fonksiyon faktöriyelinde 2. konuma ulaşır . 2. konum şu anlama gelir:
dönüş gerçekleştirildikten sonra ancak aktivasyon kaydı yapılmadan önce geçen süre
yığından kaldırıldı. Fonksiyon kodunun çarptığını hatırlayın.
özyinelemeli tarafından döndürülen değere göre n parametresinin geçerli değeri
işleve çağrı yapın. Faktöriyelden ilk dönüş, 1 değerini döndürür.
Bu etkinleştirme için etkinleştirme kaydı örneği, doğrulaması için 1 değerine sahiptir.
parametre n . Bu çarpmanın sonucu, 1, döndürülür
parametresiyle çarpılacak faktöriyelin ikinci aktivasyonuna
n için 2 olan değer. Bu adım, ilk aktivasyona 2 değerini döndürür.
Şekil 10.7
İçeriği faktöriyelde 1. konumda yığınlayın
ARI = aktivasyon kaydı örneği
Tepe
fonksiyonel değer
Parametre
Dinamik bağlantı
Ana sayfaya DÖN)
Yerel
İlk ARI
faktöriyel için
ARI
ana için
n
3
?
?
değer
n
fonksiyonel değer
Parametre
Dinamik bağlantı
Ana sayfaya DÖN)
Yerel
İlk ARI
faktöriyel için
ARI
ana için
3
?
?
n
Tepe
fonksiyonel değer
Parametre
Dinamik bağlantı
Geri dön (faktöriyel)
İkinci ARI
faktöriyel için
2
?
değer
n
fonksiyonel değer
Parametre
Dinamik bağlantı
Ana sayfaya DÖN)
Yerel
İlk ARI
faktöriyel için
ARI
ana için
3
?
?
n
fonksiyonel değer
Parametre
Dinamik bağlantı
Geri dön (faktöriyel)
İkinci ARI
faktöriyel için
2
?
n
Tepe
değer
fonksiyonel değer
Parametre
Dinamik bağlantı
Geri dön (faktöriyel)
Üçüncü ARI
faktöriyel için
1
?
İlk arama
ikinci arama
üçüncü arama

Sayfa 474
10.3 Yığın Dinamik Yerel Değişkenleri ile Alt Programları Uygulama 453
ARI = aktivasyon kaydı örneği
n
fonksiyonel değer
Parametre
Dinamik bağlantı
Ana sayfaya DÖN)
Yerel
İlk ARI
faktöriyel için
ARI
ana için
3
?
?
n
fonksiyonel değer
Parametre
Dinamik bağlantı
Geri dön (faktöriyel)
İkinci ARI
faktöriyel için
2
?
n
Tepe
2. pozisyonda
faktöriyel olarak
değer
Yerel
ARI
ana için
6
Tepe
3. pozisyonda
esas olarak
değer
fonksiyonel değer
Parametre
Dinamik bağlantı
Geri dön (faktöriyel)
Üçüncü ARI
faktöriyel için
1
1
üçüncü arama tamamlandı
Tepe
fonksiyonel değer
Parametre
Dinamik bağlantı
Ana sayfaya DÖN)
Yerel
İlk ARI
faktöriyel için
ARI
ana için
n
3
6
?
değer
2. pozisyonda
faktöriyel olarak
ilk arama tamamlandı
Nihai sonuçlar
n
fonksiyonel değer
Parametre
Dinamik bağlantı
Ana sayfaya DÖN)
Yerel
İlk ARI
faktöriyel için
ARI
ana için
3
?
?
n
Tepe
fonksiyonel değer
Parametre
Dinamik bağlantı
Geri dön (faktöriyel)
İkinci ARI
faktöriyel için
2
2
2. pozisyonda
faktöriyel olarak
değer
ikinci arama tamamlandı
Şekil 10.8
Ana ve faktöriyel yürütme sırasında içeriği yığın
bir faktöriyel için parametre değeri ile çarpılır n , 3'tür,
6'nın nihai işlevsel değerini verir, bu daha sonra ilk değere döndürülür.
çağrısı faktöryel içinde ana .

Sayfa 475
454
Bölüm 10 Alt Programları Uygulamak
10.4 İç İçe Alt Programlar
C tabanlı olmayan statik kapsamlı programlama dillerinden bazıları yığın dinamik kullanır
yerel değişkenler ve alt programların iç içe geçmesine izin verir. Bunlar arasında Fortran 95+
Ada, Python, JavaScript, Ruby ve Lua'nın yanı sıra işlevsel diller. Bunda
bölümünde, alt programların uygulanmasında en yaygın olarak kullanılan yaklaşımı inceliyoruz.
iç içe olabilen gramlar. Bu bölümün sonuna kadar, kapanışları görmezden geliyoruz.
10.4.1 Temel Bilgiler
Statik kapsamlı bir dilde yerel olmayan bir değişkene başvuru, iç içe alt
programlar iki adımlı bir erişim süreci gerektirir. Tüm statik olmayan değişkenler
yerel olmayan erişim, mevcut etkinleştirme kaydı örneklerindedir ve bu nedenle
yığında bir yerdeler. Erişim sürecinin ilk adımı,
değişkenin tahsis edildiği yığındaki etkinleştirme kaydının örneği.
İkinci kısım, değişkenin local_offset değerini kullanmaktır (aktivasyon içinde
örneğini kaydedin) erişmek için.
Doğru aktivasyon kaydı örneğini bulmak daha ilginç ve
iki adımdan daha zor. İlk olarak, belirli bir alt programda yalnızca
statik ata kapsamlarında bildirilen değişkenler görünürdür ve
erişildi. Ayrıca, tüm statik ataların aktivasyon kaydı örnekleri,
içindeki değişkenlere iç içe geçmiş bir alt program tarafından başvurulduğunda her zaman yığında
gram. Bu, statik kapsamlı alanın statik anlamsal kuralları tarafından garanti edilir.
göstergeler: Bir alt program, yalnızca tüm statik ata alt programları olduğunda çağrılabilir.
aktifler. 1 Belirli bir statik ata aktif değilse, yerel değişkenleri
depolamaya bağlı olmayacaktı, bu yüzden onlara erişime izin vermek saçma olurdu.
Yerel olmayan referansların semantiği, doğru bildirimin
çevreleyen kapsamlara bakıldığında ilk bulunandır, en yakından
önce yuvalanmış. Bu nedenle, yerel olmayan referansları desteklemek için, hepsini bulmak mümkün olmalıdır.
bu statiklere karşılık gelen yığındaki etkinleştirme kayıtlarının örnekleri
atalar. Bu gözlem, açıklanan uygulama yaklaşımına yol açar
aşağıdaki alt bölümde.
Bloklar konusunu Bölüm 10.5'e kadar ele almıyoruz, bu nedenle kalan kısımda-
Bu bölümde, tüm kapsamların alt programlar tarafından tanımlandığı varsayılmaktadır.
İşlevler C tabanlı dillerde yuvalanamadığından (yalnızca statik
bu dillerdeki kapsamlar bloklarla oluşturulanlardır), bunun tartışmaları
bölümü doğrudan bu diller için geçerli değildir.
10.4.2 Statik Zincirler
İzin veren dillerde statik kapsam belirlemenin en yaygın yolu
iç içe alt programlar statik zincirlemedir. Bu yaklaşımda, yeni bir işaretçi,
statik bağlantı adı verilen aktivasyon kaydına eklenir. Statik bağlantı , hangi
1. Kapanışlar elbette bu kuralı ihlal eder.

Sayfa 476
10.4 İç İçe Alt Programlar 455
bazen statik kapsam işaretçisi olarak adlandırılır , işlemin alt kısmına işaret eder.
statik ebeveynin bir aktivasyonunun vation kaydı örneği. İçin kullanılır
yerel olmayan değişkenlere erişim. Tipik olarak, statik bağlantı eylemde görünür.
parametrelerin altındaki vation kaydı. Statik bağlantının eklenmesi
aktivasyon kaydı, yerel ofsetlerin statik bağlantıdan farklı olmasını gerektirir
içermiyor. Daha önce iki aktivasyon kayıt elemanına sahip olmak yerine
parametreler, şimdi üç tane var: dönüş adresi, statik bağlantı ve
dinamik bağlantı.
Bir statik zincir , belirli aktivasyon bağlamak statik bir bağlantı zinciridir
yığındaki örnekleri kaydedin. P alt programının yürütülmesi sırasında ,
aktivasyon kaydı örneğinin statik bağlantısı bir aktivasyon kaydına işaret ediyor
P'nin statik ana program biriminin örneği . Bu örneğin statik bağlantı noktaları
sırayla P'nin statik büyük ebeveyn program biriminin etkinleştirme kaydı örneğine,
Eğer biri varsa. Böylece, statik zincir, bir sistemin tüm statik atalarını birbirine bağlar.
önce statik ebeveyn sırasına göre alt programı yürütmek. Bu zincir,
Statik kapsamda yerel olmayan değişkenlere erişimleri uygulamak için kullanılabilir.
Diller.
kullanarak yerel olmayan bir değişkenin doğru aktivasyon kaydı örneğini bulma
statik bağlantılar nispeten basittir. Yerel olmayan bir referans yapıldığında
değişken, değişkeni içeren aktivasyon kaydı örneği bulunabilir
statik bir ata aktivasyon kaydı örneğine kadar statik zinciri arayarak
değişkeni içerdiği bulunmuştur. Ancak, bundan çok daha kolay olabilir.
Kapsamların iç içe geçtiği derleme zamanında bilindiğinden, derleyici caydırabilir.
benimki sadece bir referansın yerel olmadığı değil, aynı zamanda statik zincirin uzunluğu
içeren aktivasyon kaydı örneğine ulaşmak için izlenmesi gereken
yerel olmayan nesne.
static_depth belirten bir statik kapsamla ilişkili bir tamsayı olsun .
en dıştaki kapsamda ne kadar derine yuvalanmış. olmayan bir program birimi
başka bir birimin içine yerleştirilmiş, statik_derinliği 0'a sahiptir. Alt program A tanımlanmışsa
Alt program Bir nonnested programı biriminde, onun static_depth 1'dir A içeriyor
iç içe geçmiş bir B alt programının tanımı , ardından B'nin statik_derinliği 2'dir.
Doğru aktivasyona ulaşmak için gereken statik zincirin uzunluğu
X değişkenine yerel olmayan bir başvuru için kayıt örneği tam olarak farktır
X referansını içeren alt programın statik_derinliği ile
X için bildirimi içeren alt programın statik_derinliği . Bu fark-
referans, başvurunun nesting_depth veya chain_offset olarak adlandırılır . bu
gerçek referans, sıralı bir tamsayı çifti ile temsil edilebilir (chain_offset,
local_offset), burada chain_offset, doğru etkinliğe giden bağlantıların sayısıdır.
kayıt örneği (local_offset, Bölüm 10.3.2'de açıklanmıştır). Örneğin,
aşağıdaki iskelet Python programını düşünün:
# Küresel kapsam
. . .
tanım f1():
tanım f2():
tanım f3():

Sayfa 477
456
Bölüm 10 Alt Programları Uygulamak
. . .
# f3'ün sonu
. . .
# f2'nin sonu
. . .
# f1'in sonu
Genel kapsamın statik_derinlikleri, f1 , f2 ve f3 , 0, 1, 2 ve 3'tür.
nazikçe. f3 prosedürü f1 içinde bildirilen bir değişkene başvuruyorsa , chain_offset
bu referans 2 (arasında static_depth olacaktır f3 eksi static_depth arasında
f1 ). f3 prosedürü f2 içinde bildirilen bir değişkene başvuruyorsa , bunun chain_offset'i
bu referans 1 olacaktır. Yerlilere yapılan referanslar aynı
0'lık bir chain_offset ile, ancak statik işaretçi kullanmak yerine mekanizma
değişkenin bulunduğu alt programın aktivasyon kaydı örneğine
temel adres olarak bildirildiğinde, EP kullanılır.
Yerel olmayan erişimlerin tam sürecini göstermek için aşağıdakileri göz önünde bulundurun:
alçaltan iskelet Ada programı:
prosedür Main_2 olduğu
X : Tamsayı;
prosedür Bigsub olduğu
A, B, C : Tamsayı;
prosedür Sub1 olduğu
A, D : Tamsayı;
başlamak - Sub1
A := B + C;
1
. . .
son ; -- Sub1'in
prosedür Sub2 (X: Integer) olduğu
B, E : Tamsayı;
prosedür sub3 olduğu
C, E : Tamsayı;
başlamak - sub3 arasında
. . .
alt1;
. . .
E := B + A;
2
son ; -- Sub3'ün
başlangıç -- of Sub2
. . .
alt3;
. . .
A := D + E;
3
son ; -- Sub2'nin
başlamak - Bigsub arasında
. . .
Alt2(7);

Sayfa 478
10.4 İç İçe Alt Programlar 457
. . .
son; -- Bigsub'ın
başlamak - Main_2 arasında
. . .
Bigsub;
. . .
son; -- / Main_2
Prosedür çağrılarının sırası
Main_2, Bigsub'ı çağırır
Bigsub, Sub2'yi çağırır
Sub2, Sub3'ü çağırır
Sub3, Sub1'i çağırır
Bu programda yürütme 1. noktaya ilk geldiğinde yığın durumu şöyledir:
Şekil 10.9'da gösterilmiştir.
Sub1 prosedüründe 1 konumunda , referans yerel değişkene yapılır,
Bir değil, yerel olmayan değişken için A dan Bigsub . A'ya yapılan bu referans ,
chain_offset/local_offset çifti (0, 3). B'ye yapılan referans , yerel olmayan B'ye yöneliktir.
dan Bigsub . (1, 4) çifti ile temsil edilebilir. local_offset 4'tür,
çünkü bir 3 ofset ilk yerel değişken olacaktır ( Bigsub'un hiçbir parametresi yoktur)
eter). Basit bir arama yapmak için dinamik bağlantı kullanılmışsa, şunu unutmayın:
B değişkeni için bir bildirim içeren bir etkinleştirme kaydı örneği ,
Sub2'de bildirilen B değişkenini bulun , bu yanlış olur. (1, 4) ise
çift dinamik zinciri ile kullanılmıştır, değişken E adlı sub3 olacaktır
Kullanılmış. Ancak statik bağlantı, Bigsub için aktivasyon kaydına işaret eder ,
B'nin doğru sürümüne sahip olan . Değişken B de Sub2 değil
bu noktada referans ortamı ve (doğru) erişilebilir değil. bu
referans C 1 noktasında olan C 'de tanımlandığı Bigsub temsil edilir,
çift ​​tarafından (1, 5).
Sub1 yürütmesini tamamladıktan sonra , için aktivasyon kaydı örneği
Sub1 yığından kaldırılır ve kontrol Sub3'e döner . referans-
Sub3'teki 2. konumdaki E değişkenine ence yereldir ve (0, 4) çiftini kullanır
erişim için. B değişkenine yapılan başvuru , Sub2'de bildirilene yöneliktir ,
çünkü bu, böyle bir bildirimi içeren en yakın statik atadır.
(1, 4) çifti ile erişilir. Çünkü local_offset 4 olduğu B ilk
Sub1'de bildirilen değişken ve Sub2'nin bir parametresi vardır. referans
Değişken A etmektir A ilan Bigsub , ne çünkü sub3 ne de
statik üst Sub2 , A adlı bir değişken için bir bildirime sahiptir . referans alınır
(2, 3) çifti ile.
Sonra sub3 yürütme, aktivasyon kayıt örneği tamamlar sub3
için yalnızca etkinleştirme kaydı örnekleri bırakarak yığından kaldırılır.
Main_2 , Bigsub ve Sub2 . Sub2'de 3 konumunda , değişkene yapılan referans
güçlü bir etmektir A içinde Bigsub sadece tanımlama bölümüne sahiptir, A arasında
aktif rutinler Bu erişim çifti (1, 3) ile yapılır. Bu pozisyonda, orada

Sayfa 479
458
Bölüm 10 Alt Programları Uygulamak
D değişkeni için bir bildirim içeren görünür bir kapsam değildir , bu nedenle bu başvuru
için D statik semantik hatadır. Derleyici ne zaman hata algılanırsa
chain_offset/local_offset çiftini hesaplamaya çalıştı. Referans E olduğu
yerel E olarak Sub2 çifti (0, 5) ile erişilebilir.
Özetle, 1, 2 ve 3 noktalarında A değişkenine yapılan referanslar şöyle olacaktır:
aşağıdaki noktalarla temsil edilir:
• (0, 3) (yerel)
• (2, 3) (iki seviye ötede)
• (1, 3) (bir seviye ötede)
Şekil 10.9
İçeriği şurada yığın:
konum 1'de
ana_2 programı
ARI = aktivasyon kaydı örneği
B
Yerel
Yerel
Parametre
Dinamik bağlantı
statik bağlantı
ARI için
alt2
x
E
B
A
x
C
C
E
Yerel
Yerel
Dinamik bağlantı
statik bağlantı
Geri Dön (Sub2'ye)
ARI için
alt3
A
D
Tepe
Yerel
Yerel
Yerel
Dinamik bağlantı
statik bağlantı
Dön (Main_2'ye)
Yerel
ARI için
Bigsub
ARI için
ana_2
Dönüş (Bigsub'a)
Yerel
Yerel
Dinamik bağlantı
statik bağlantı
(Sub3'e dön)
ARI için
alt1

Sayfa 480
10.4 İç İçe Alt Programlar 459
Bu noktada statik zincirin nasıl korunduğunu sormak mantıklıdır.
program yürütme. Bakımı çok karmaşıksa,
basit ve etkili önemsiz olacaktır. Burada şu parametreleri varsayıyoruz:
alt programlar uygulanmaz.
Statik zincir, her alt program çağrısı ve dönüşü için değiştirilmelidir.
Geri dönüş kısmı önemsizdir: Alt program sona erdiğinde, aktivasyonu
kayıt örneği yığından kaldırılır. Bu kaldırma işleminden sonra yeni
üst etkinleştirme kaydı örneği, alt programı çağıran birimin örneğidir.
yürütmesi yeni sonlandırılan gram. Çünkü bundan statik zincir
aktivasyon kaydı örneği hiç değiştirilmedi, tıpkı olduğu gibi doğru çalışıyor
diğer alt programa çağrıdan önce yaptı. Bu nedenle başka bir işlem yapılmaz.
gereklidir.
Bir alt program çağrısında gereken eylem daha karmaşıktır. rağmen
doğru üst kapsam derleme zamanında kolayca belirlenir, en son
ana kapsamın aktivasyon kaydı örneği, şu anda bulunmalıdır.
arama. Bu, üzerindeki aktivasyon kaydı örneklerine bakarak yapılabilir.
üst kapsamdan ilki bulunana kadar dinamik zincir. ama, bu
alt program bildirimlerini ve referanslarını ele alarak aramadan kaçınılabilir
tam olarak değişken bildirimleri ve referansları gibi. Derleyici karşılaştığında
bir alt program çağrısında, diğer şeylerin yanı sıra alt programı belirler.
statik bir atası olması gereken, çağrılan alt programı bildiren
arama rutini. Daha sonra yuvalama_derinliğini veya çevreleme sayısını hesaplar.
çağıran ve çağrılan alt programı bildiren alt program arasındaki kapsamlar
programı. Bu bilgiler saklanır ve alt program tarafından erişilebilir
yürütme sırasında arayın. Çağrı sırasında, çağrılan alt öğenin statik bağlantısı
programın aktivasyon kaydı örneği, statik değerden aşağı hareket ettirilerek belirlenir.
arayanın zinciri hesaplanan yuvalama_derinliğine eşit bağlantı sayısı
derleme zamanında.
Main_2 programını ve içinde gösterilen yığın durumunu tekrar düşünün .
Şekil 10.9. Çağrısına başta Sub1 içinde sub3 , derleyici Nest- belirler
Sub3'ün (arayan) ing_depth prosedür içinde iki seviye olması
Bigsub olan Sub1 adlı prosedürü açıkladı . Sub1'e çağrı yapıldığında
içinde sub3 yürütülür, bu bilgiler aslında son statik bağlantısını ayarlamak için kullanılır
Sub1 için vation kaydı örneği . Bu statik bağlantı, etkinliğe işaret edecek şekilde ayarlanmıştır.
statikteki ikinci statik bağlantı tarafından işaret edilen kayıt örneği
arayanın aktivasyon kaydı örneğinden zincir. Bu durumda arayan kişi
Statik bağlantısı üst öğesinin etkinleştirme kaydı örneğine işaret eden Sub3 (bu
arasında Sub2 ). Sub2 noktaları için etkinleştirme kaydı örneğinin statik bağlantısı
Bigsub için aktivasyon kaydı örneğine . Böylece, yeni için statik bağlantı
Sub1 için aktivasyon kaydı örneği , aktivasyon kaydını gösterecek şekilde ayarlandı
Bigsub için örnek .
Bu yöntem, parametreler dışında tüm alt program bağlantıları için çalışır.
olan alt programlardır.
Yerel olmayan değişkenlere erişmek için statik zinciri kullanmanın bir eleştirisi şudur:
statik üst öğe maliyetinin ötesindeki kapsamlardaki değişkenlere yapılan başvurular, başvurulardan daha pahalıdır.
yerliler için. Statik zincir izlenmelidir, kapsam başına bir bağlantı

Sayfa 481
460
Bölüm 10 Alt Programları Uygulamak
beyannameye yapılan atıftan. Neyse ki, uygulamada, referanslar
uzak yerel olmayan değişkenler nadirdir, bu nedenle bu ciddi bir sorun değildir. Bir diğeri
Statik zincir yaklaşımının eleştirisi, bir programcı için zor olmasıdır.
yerel olmayan referansların maliyetlerini tahmin etmek için zaman açısından kritik bir program üzerinde çalışmak,
çünkü her referansın maliyeti, referanslar arasındaki yuvalama derinliğine bağlıdır.
referans ve beyanın kapsamı. Bu sorunu daha da karmaşık hale getiren
sonraki kod değişikliklerinin yuvalama derinliklerini değiştirebileceği, dolayısıyla
Hem değiştirilen kodda hem de muhtemelen
değişikliklerden uzak kod.
Statik zincirlere bazı alternatifler geliştirilmiştir, özellikle de
görüntü adı verilen yardımcı bir veri yapısı kullanan yaklaşım. Ancak hiçbiri
alternatiflerin statik zincir yöntemine göre daha üstün olduğu bulunmuştur,
hala en yaygın kullanılan yaklaşımdır. Bu nedenle, alternatiflerin hiçbiri
tifler burada tartışılır.
Bu bölümde açıklanan süreçler ve veri yapıları doğru bir şekilde
işlevlerin işlevi döndürmesine izin vermeyen dillerde kapanışları uygulayın
işlevlerin değişkenlere atanmasına izin vermez. Ancak, onlar
bu işlemlerden birine veya her ikisine izin veren diller için yetersizdir.
Bu tür ortamlarda yerel olmayanlara erişimi uygulamak için birkaç yeni mekanizmaya ihtiyaç vardır.
Diller. İlk olarak, bir alt program bir iç içe yerleştirmeden bir değişkene erişiyorsa ancak
global kapsam, bu değişken yalnızca etkinleştirme kaydında saklanamaz
onun ev kapsamı. Bu aktivasyon kaydı, alt kayıttan önce yeniden tahsis edilebilir.
ihtiyacı olan program etkinleştirilir. Bu tür değişkenler ayrıca
yığın ve verilen sınırsız uzatma (ömürleri bütünün ömrüdür)
programı). İkincisi, alt programlar yerel olmayanlara erişmek için mekanizmalara sahip olmalıdır.
yığında depolanır. Üçüncüsü, yığınla ayrılmış değişkenler
yerel olarak erişilenler, yığın sürümleri her güncellendiğinde güncellenmelidir.
Açıkça, bunlar, uygulama statik kapsamının önemsiz olmayan uzantılarıdır.
statik zincirler kullanarak.
10.5 Blok
Bölüm 5'ten hatırlayın, C-tabanlı diller de dahil olmak üzere bir dizi dil
diller, blok adı verilen değişkenler için kullanıcı tarafından belirlenen yerel kapsamlar sağlar .
Bir blok örneği olarak aşağıdaki kod segmentini göz önünde bulundurun:
{ int sıcaklık;
temp = liste[üst];
liste[üst] = liste[alt];
liste[alt] = sıcaklık;
}

Sayfa 482
10.5 Blok 461
C tabanlı dillerde bir blok, bileşik bir ifade olarak belirtilir.
bir veya daha fazla veri tanımıyla başlar. Değişken sıcaklığın ömrü
önceki blokta, kontrol bloğa girdiğinde başlar ve
kontrol bloktan çıkar. Böyle bir yerel kullanmanın avantajı,
else olarak bildirilen aynı ada sahip herhangi bir değişkene müdahale edin.
programın neresinde veya daha spesifik olarak referans ortamında
bloğun.
Bloklar, açıklanan statik zincir süreci kullanılarak uygulanabilir.
İç içe geçmiş alt programları uygulamak için Bölüm 10.4'te. Bloklar şu şekilde işlem görür:
her zaman aynı yerden çağrılan parametresiz alt programlar
programı. Bu nedenle her bloğun bir aktivasyon kaydı vardır. Onun bir örneği
blok her çalıştırıldığında aktivasyon kaydı oluşturulur.
Bloklar ayrıca farklı ve biraz daha basit ve
daha verimli bir yol. Blok değişkeni için gereken maksimum depolama miktarı
bir programın yürütülmesi sırasında herhangi bir zamanda mümkün olanlar statik olarak caydırılabilir-
mayınlı, çünkü bloklar kesinlikle metinsel sırayla girilir ve çıkılır. Bu
aktivasyondaki yerel değişkenlerden sonra alan miktarı tahsis edilebilir
kayıt. Tüm blok değişkenleri için ofsetler statik olarak hesaplanabilir, bu nedenle blok değişkeni
yetenekler tam olarak yerel değişkenlermiş gibi ele alınabilir.
Örneğin, aşağıdaki iskelet programını düşünün:
geçersiz ana() {
int x, y, z;
süre ( . . . ) {
int a, b, c;
. . .
süre ( . . . ) {
int d, e;
. . .
}
}
süre ( . . . ) {
int f, g;
. . .
}
. . .
}
Bu program için Şekil 10.10'da gösterilen statik bellek düzeni şu şekilde olabilir:
Kullanılmış. f ve g'nin a ve b ile aynı bellek konumlarını işgal ettiğini unutmayın , çünkü
Bir ve B de blok önce (çıkılır yığın kapalı attı edilir f ve g edilir
tahsis edilmiştir).

Sayfa 483
462
Bölüm 10 Alt Programları Uygulamak
10.6 Dinamik Kapsam Belirleme Uygulaması
Yerel değişkenlerin ve yerel olmayan referansların en az iki farklı yolu vardır.
bunlara erişim dinamik kapsamlı bir dilde uygulanabilir: derin erişim
ve sığ erişim. Derin erişim ve sığ erişimin kavram olmadığını unutmayın.
Derin ve sığ ciltleme ile ilgili. bağlama arasındaki önemli bir fark
ve erişim, derin ve sığ bağlamaların farklı anlambilimle sonuçlanmasıdır; derin
ve sığ erişimler yok.
10.6.1 Derin Erişim
Yerel değişkenler yığın dinamik ise ve bir
dinamik kapsamlı dil, yerel olmayan değişkenlere yapılan referanslar şu şekilde çözülebilir:
diğer alt programların aktivasyon kaydı örneklerinde arama yapmak
En son etkinleştirilenden başlayarak, şu anda etkin olan Bu
kavram, statik kapsamlı bir sistemde yerel olmayan değişkenlere erişmeye benzer.
iç içe alt programlara sahip dil, bunun dışında dinamik —
statik—zincir takip edilir. Dinamik zincir, tüm alt programı birbirine bağlar
Şekil 10.10
Blok değişkeni
bloklar olduğunda depolama
tedavi edilmiyor
parametresiz olarak
prosedürler
yerliler
e
D
C
b ve g
bir ve f
z
y
x
Engellemek
değişkenler
aktivasyon
kayıt örneği
için
ana

Sayfa 484
10.6 Dinamik Kapsam Belirlemeyi Uygulama 463
aktivasyon kaydı örnekleri, etkinleştirildikleri sıranın tersinde
vated. Bu nedenle, dinamik zincir tam olarak referans için gerekli olan şeydir.
dinamik kapsamlı bir dilde yerel olmayan değişkenler. Bu yönteme derin denir
erişim , çünkü erişim yığının derinliklerinde arama gerektirebilir.
Aşağıdaki örnek iskelet programını göz önünde bulundurun:
geçersiz sub3() {
int x, z;
x = u + v;
. . .
}
geçersiz sub2() {
int w, x;
. . .
}
geçersiz sub1() {
int v, w;
. . .
}
geçersiz ana() {
int v, u;
. . .
}
Bu program, bir program görünümü veren bir söz dizimi ile yazılmıştır.
C tabanlı bir dilde, ancak belirli bir dilde olması amaçlanmamıştır.
Aşağıdaki işlev çağrısı dizisinin gerçekleştiğini varsayalım:
ana çağrılar alt1
abon1 çağrılar abon1
abon1 çağrılar sub2
sub2 , sub3'ü çağırır
Şekil 10.11, bundan sonra sub3 fonksiyonunun yürütülmesi sırasında yığını gösterir.
arama sırası. Aktivasyon kaydı örneklerinin statik olmadığına dikkat edin.
dinamik kapsamlı bir dilde hiçbir amaca hizmet etmeyecek bağlantılar.
sub3 işlevinde x , u ve v değişkenlerine yapılan başvuruları göz önünde bulundurun .
x'e yapılan başvuru, sub3 için etkinleştirme kaydı örneğinde bulunur . bu
u referansı, üzerindeki tüm aktivasyon kaydı örnekleri aranarak bulunur.
yığın, çünkü bu ada sahip tek var olan değişken main içindedir . Bu
arama, dört dinamik bağlantının izlenmesini ve 10 değişken adının incelenmesini içerir.
v'ye yapılan başvuru en son (dinamik zincirde en yakın) içinde bulunur.
sub1 alt programı için aktivasyon kaydı örneği .

Sayfa 485
464
Bölüm 10 Alt Programları Uygulamak
için derin erişim yöntemi arasında iki önemli fark vardır.
dinamik kapsamlı bir dilde yerel olmayan erişim ve statik zincir yöntemi
statik kapsamlı diller. Birincisi, dinamik kapsamlı bir dilde,
derleme zamanında aranması gereken zincirin uzunluğunu belirlemek için.
Zincirdeki her etkinleştirme kaydı örneği, birinciye kadar aranmalıdır.
değişkenin örneği bulunur. Dinamik kapsamlı lan-
göstergeler genellikle statik kapsamlı dillerden daha yavaş yürütme hızlarına sahiptir.
İkincisi, aktivasyon kayıtları, arama için değişkenlerin adlarını saklamalıdır.
süreç, oysa statik kapsamlı dil uygulamalarında yalnızca değerler
gerekmektedir. (Statik kapsam belirleme için adlar gerekli değildir, çünkü tüm değişkenler
chain_offset/local_offset çiftleriyle temsil edilir.)
10.6.2 Sığ Erişim
Sığ erişim, alternatif değil, alternatif bir uygulama yöntemidir
anlambilim. Daha önce belirtildiği gibi, derin erişim ve sığ erişim
Özdeş. Sığ erişim yönteminde, alt programlarda bildirilen değişkenler
bu alt programların aktivasyon kayıtlarında saklanmaz. Çünkü
dinamik kapsam belirleme, herhangi bir belirli değişkenin en fazla bir görünür versiyonu vardır.
Şekil 10.11
Yığın içeriği
dinamik kapsamlı
program
ARI = aktivasyon kaydı örneği
v
Yerel
Yerel
Dinamik bağlantı
Ana sayfaya DÖN)
Yerel
Yerel
w
v
Geri dön (alt1'e)
Dinamik bağlantı
Yerel
Yerel
Dinamik bağlantı
Geri dön (alt1'e)
z
x
x
w
Dinamik bağlantı
Yerel
Yerel
Geri dön (alt2'ye)
Yerel
Yerel
ARI
sub3 için
ARI
sub2 için
ARI
sub1 için
ARI
sub1 için
ARI
ana için
w
v
sen

Sayfa 486
10.6 Dinamik Kapsam Belirlemeyi Uygulama 465
Belirli bir zamanda isim, çok farklı bir yaklaşım alınabilir. Bir varyasyonu
sığ erişim, eksiksiz bir şekilde her değişken adı için ayrı bir yığına sahip olmaktır.
programı. Belirli bir ada sahip yeni bir değişken, bir karar tarafından her oluşturulduğunda,
çağrılan bir alt programın başlangıcındaki laration, değişken
adı için yığının en üstünde bir hücre verilir. isme yapılan her atıf
bu adla ilişkili yığının üstündeki değişkene, çünkü üst
biri en son oluşturulandır. Bir alt program sona erdiğinde, ömürler
yerel değişkenleri sona erer ve bu değişken adlarının yığınları açılır.
Bu yöntem, değişkenlere hızlı başvurulara izin verir, ancak yığınları
alt programların giriş ve çıkışları maliyetlidir.
Şekil 10.12, önceki örnek program için değişken yığınlarını göstermektedir.
Şekil 10.11'deki yığınla gösterilen durumla aynı.
Sığ erişim uygulamak için başka bir seçenek de merkezi bir tablo kullanmaktır.
bir programdaki her farklı değişken adı için bir konuma sahip olan. İle birlikte
Her girişte, adın aktif olup olmadığını gösteren bir bit tutulur.
geçerli bir bağlama veya değişken ilişkilendirmeye sahiptir. Herhangi bir değişkene herhangi bir erişim
daha sonra merkezi masaya bir ofset olun. Ofset statiktir, bu nedenle erişim
hızlı olabilir. SNOBOL uygulamaları merkezi tablo uygulamasını kullanır
teknik.
Merkezi bir masanın bakımı basittir. Bir alt program çağrısı
tüm yerel değişkenlerinin mantıksal olarak merkezi tabloya yerleştirilmesini gerektirir. Eğer
yeni değişkenin merkezi tablodaki konumu zaten etkindir - yani,
ömrü henüz bitmemiş (belirtilen) bir değişken içeriyorsa
aktif bit tarafından)—bu değerin kullanım ömrü boyunca bir yere kaydedilmesi gerekir.
yeni değişken. Bir değişken ömrüne ne zaman başlasa, içindeki aktif bit
orta masa pozisyonu ayarlanmalıdır.
Orta sehpanın tasarımında çeşitli varyasyonlar olmuştur ve
geçici olarak değiştirildiklerinde değerlerin saklanma biçiminde. Bir varyasyon
tüm kayıtlı nesnelerin depolandığı bir "gizli" yığına sahip olmaktır. Çünkü alt-
program çağrıları ve geri dönüşleri ve dolayısıyla yerel değişkenlerin yaşam süreleri iç içedir,
bu iyi çalışıyor.
İkinci varyasyon, belki de uygulanması en temiz ve en ucuz olanıdır.
ment. Yalnızca geçerli sürümü saklayan tek hücreli merkezi bir tablo kullanılır
benzersiz bir adla her değişkenin. Değiştirilen değişkenler
Şekil 10.12
kullanmanın bir yöntemi
sığ erişim
dinamik uygulamak
kapsam belirleme
ana
ana
alt2
alt3
alt1
sen
v
x
z
w
alt1
alt3
alt1
alt1
alt2
(Yığın hücrelerindeki adlar,
değişken bildiriminin program birimleri.)

Sayfa 487
466
Bölüm 10 Alt Programları Uygulamak
değiştirme değişkenini yaratan alt programın aktivasyon kaydı.
Bu bir yığın mekanizmasıdır, ancak zaten var olan yığını kullanır, bu nedenle yeni
ek yük minimumdur.
Yerel olmayan değişkenlere sığ ve derin erişim arasındaki seçim,
alt program çağrılarının ve yerel olmayan referansların göreli frekansları hakkında. bu
derin erişim yöntemi, hızlı alt program bağlantısı sağlar, ancak
yereller, özellikle uzak yerel olmayanlara yapılan göndermeler (çağrı zinciri açısından),
pahalı. Sığ erişim yöntemi, yerel olmayanlara çok daha hızlı başvurular sağlar,
özellikle uzak yerel olmayanlar, ancak alt program bağlantısı açısından daha maliyetlidir.
ÖZET
Alt program bağlantı semantiği, uygulama tarafından birçok eylem gerektirir.
“Basit” alt programlar söz konusu olduğunda, bu eylemler nispeten basittir. de
çağrı, yürütme durumu kaydedilmelidir, parametreler ve dönüş adresi
çağrılan alt programa geçirilmeli ve kontrol aktarılmalıdır. saat
dönüş, sonuca göre geçiş ve değere göre sonuç parametrelerinin değerleri
bir fonksiyon ise, geri dönüş değeri ile birlikte geri aktarılmalıdır.
durum geri yüklenmeli ve kontrol arayana geri aktarılmalıdır. İçinde
yığın dinamik yerel değişkenlere ve iç içe alt programlara sahip diller, alt program
gram bağlantısı daha karmaşıktır. Birden fazla aktivasyon kaydı olabilir
örnek, bu örnekler çalışma zamanı yığınında depolanmalıdır ve statik ve
dinamik bağlantılar, etkinleştirme kaydı örneklerinde korunmalıdır. statik
bağlantı, statik kapsamlı dillerde yerel olmayan değişkenlere başvurulara izin vermektir.
Yığın dinamik yerel değişkenler ve iç içe geçmiş dillerde alt programlar
alt programların iki bileşeni vardır: statik olan gerçek kod ve
yığın dinamik olan aktivasyon kaydı. Aktivasyon kaydı örnekleri şunları içerir:
diğer şeylerin yanı sıra resmi parametreler ve yerel değişkenler.
Dinamik kapsamlı bir dilde yerel olmayan değişkenlere erişim uygulanabilir.
dinamik zincirin kullanımıyla veya bazı merkezi değişken tabloları aracılığıyla belirtilir
yöntem. Dinamik zincirler, yavaş erişimler, ancak hızlı aramalar ve geri dönüşler sağlar. bu
merkezi tablo yöntemleri hızlı erişim sağlar, ancak yavaş aramalar ve geri dönüşler sağlar.
İNCELEME SORULARI
1. Bu bölümde “basit” alt programlar için kullanılan tanım nedir?
2. Arayan veya aranan kişiden hangisi yürütme durumu bilgisini kaydeder?
3. Bir alt programa bağlantı için ne saklanmalıdır?
4. Bir bağlayıcının görevi nedir?
5. Yığınla alt programları uygulamanın iki nedeni nedir?
dinamik yerel değişkenler, basit uygulamadan daha zordur
alt programlar?

Sayfa 488
Problem Seti 467
6. Aktivasyon kaydı ile aktivasyon arasındaki fark nedir?
kayıt örneği?
7. Dönüş adresi, dinamik bağlantı ve parametreler neden
aktivasyon kaydının alt kısmı?
8. Ne tür makineler parametreleri iletmek için sıklıkla kayıtları kullanır?
9. Statik kapsamlı bir değişkende yerel olmayan bir değişkeni bulmanın iki adımı nelerdir?
yığın dinamik yerel değişkenler ve iç içe alt programlarla dil?
10. Statik zincir , statik_derinlik , iç içe_derinlik ve zincir_kaygı tanımlayın .
11. EP nedir ve amacı nedir?
12. Statik zincir yönteminde değişkenlere yapılan referanslar nasıl temsil edilir?
13. İzin vermeyen yaygın olarak kullanılan üç programlama dilini adlandırın.
iç içe alt programlar
14. Statik zincir yöntemiyle ilgili iki olası sorun nedir?
15. Blokları uygulamanın iki yöntemini açıklayın.
16. Dinamik kapsam belirlemeyi uygulamaya yönelik derin erişim yöntemini tanımlayın.
17. Dinamik kapsam belirleme uygulamasının sığ erişim yöntemini tanımlayın.
18. Derin erişim yöntemi arasındaki iki fark nedir?
dinamik kapsamlı dillerde ve statik zincirde yerel olmayan erişim
statik kapsamlı diller için yöntem?
19. Derin erişim yönteminin verimliliğini sığ erişim yöntemiyle karşılaştırın.
hem aramalar hem de yerel olmayan erişimler açısından erişim yöntemi.
PROBLEM SETİ
1. Statik ve
dinamik zincirler, yürütme aşağıdaki iskelette 1. konuma ulaştığında
etal programı. Bigsub'ın 1. seviyede olduğunu varsayın .
prosedür Bigsub olduğu
Prosedür A olduğu
prosedür B olduğu
başlamak -- of B
. . .
1
son ; -- B'nin
Prosedür C olan
başlamak -- of C
. . .
B;
. . .
son ; -- C'nin

Sayfa 489
468
Bölüm 10 Alt Programları Uygulamak
Başlamak -- A'nın
. . .
C;
. . .
son ; -- A'nın
başlamak - Bigsub arasında
. . .
A;
. . .
son ; -- Bigsub'ın
2. Statik ve
dinamik zincirler, yürütme aşağıdaki şemada 1. konuma ulaştığında
ölümcül program Bigsub'ın 1. seviyede olduğunu varsayın .
prosedür Bigsub olduğu
MySum : Kayan;
Prosedür A olduğu
X : Tamsayı;
prosedür B (Toplam: Float) olduğu
Y, Z : Yüzer;
başlamak -- of B
. . .
C(Z)
. . .
son ; -- B'nin
Başlamak -- A'nın
. . .
B(X);
. . .
son ; -- A'nın
Prosedür C (erik: Float) olduğu
başlamak -- of C
. . .
1
son ; -- C'nin
L : Şamandıra;
başlamak - Bigsub arasında
. . .
A;
. . .
son ; -- Bigsub'ın
3. Statik ve
dinamik zincirler, yürütme aşağıdaki iskelette 1. konuma ulaştığında
etal programı. Bigsub'ın 1. seviyede olduğunu varsayın .

Sayfa 490
Problem Seti 469
prosedür Bigsub olduğu
Prosedür A (Bayrak: Boolean) olduğunu
prosedür B olduğu
. . .
Yanlış);
son ; -- B'nin
Başlamak -- A'nın
eğer bayrak
sonra B;
başka C;
. . .
son ; -- A'nın
Prosedür C olan
Prosedür D olan
. . .
1
son ; -- D
. . .
D;
son ; -- C'nin
başlamak - Bigsub arasında
. . .
bir ( doğru );
. . .
son ; -- Bigsub'ın
Yürütmenin D' ye ulaşması için bu programın çağrı sırası şöyledir:
Bigsub çağırır A
A , B'yi arar
B , A'yı arar
A , C'yi arar
C D'yi çağırır
4. Yığını, aşağıdakiler de dahil olmak üzere tüm etkinleştirme kaydı örnekleriyle birlikte gösterin.
dinamik zincir, yürütme aşağıdaki konum 1'e ulaştığında
ske letal programı. Bu program, uygulamak için derin erişim yöntemini kullanır.
dinamik kapsam belirleme.
geçersiz eğlence1() {
yüzer a;
. . .
}
geçersiz eğlence2() {
int b, c;
. . .
}

Sayfa 491
470
Bölüm 10 Alt Programları Uygulamak
geçersiz fun3() {
yüzer d;
. . .
1
}
geçersiz ana() {
karakter e, f, g;
. . .
}
Fun3'e ulaşmak için bu programın çağrı sırası şu şekildedir :
ana çağrılar fun2
FUN2 aramalar fun1
fun1 aramalar fun1
fun1 aramalar fun3
5. Problem 4'teki programın aşağıdaki formül kullanılarak uygulandığını varsayın:
Her değişken adı için bir yığın kullanan sığ erişim yöntemi. Göstermek
yürütme varsayılarak fun3 yürütme zamanı için yığınlar
gösterilen aramalar dizisi aracılığıyla bu noktaya kadar yolunu buldu.
Sorun 4.
6. Java yöntemlerinde yerel değişkenler dinamik olarak
Her aktivasyonun başlangıcında, değer hangi koşullar altında olabilir?
belirli bir aktivasyonda yerel bir değişkenin önceki değerini korur.
ous aktivasyonu?
7. Bu bölümde, yerel olmayan değişkenlere bir
dinamik zinciri kullanan dinamik kapsamlı dil, değişken adları
değerlerle aktivasyon kayıtlarında saklanmalıdır. Bu aslında olsaydı
yapıldığında, her yerel olmayan erişim bir dizi maliyetli dize gerektirecektir.
isimler üzerinde karşılaştırmalar. Bu dize karşılaştırmalarına bir alternatif tasarlayın
bu daha hızlı olurdu.
8. Pascal, yerel olmayan hedeflerle goto'lara izin verir. Bu tür ifadeler nasıl
yerel olmayan değişken erişim için statik zincirler kullanılmışsa ele alınabilir mi? İpucu :
Statik parametrenin doğru aktivasyon kaydı örneğinin yolunu düşünün.
yeni yürürlüğe giren bir prosedürün ent'i bulunur (bkz. Bölüm 10.4.2).
9. Statik zincir yöntemi, iki statik kullanılarak biraz genişletilebilir.
her bir etkinleştirme kaydı örneğindeki bağlantılar, ikincisinin
statik büyük ebeveyn etkinleştirme kaydı örneği. Bu nasıl yaklaşım
alt program bağlantısı ve yerel olmayan referanslar için gereken süreyi etkiler mi?
10. Bir iskelet programı ve bir eylemle sonuçlanan bir çağrı dizisi tasarlayın.
Statik ve dinamik bağlantıların farklılığa işaret ettiği vation kaydı örneği
çalışma zamanı yığınında etkin aktivasyonla kaydedilmiş örnekler.

Sayfa 492
Programlama Alıştırmaları 471
11. Bir derleyici, blokları uygulamak için statik zincir yaklaşımını kullanıyorsa,
alt programlar için aktivasyon kayıtlarındaki girişlerden hangisinin gerekli olduğu
bloklar için aktivasyon kayıtlarında?
12. Üç farklı mimarinin alt program çağrı komutlarını inceleyiniz.
en az bir CISC makinesi ve bir RISC makinesi dahil olmak üzere,
ve yeteneklerinin kısa bir karşılaştırmasını yazın. (Bunların tasarımı
yönergeler genellikle derleyici yazarının bilgilerinin en azından bir kısmını belirler.
alt program bağlantısının tasarımı.)
PROGRAMLAMAALIŞTIRMALAR
1. Biri tek bir alt program alan iki alt program içeren bir program yazın.
parametre ve bu parametre üzerinde bazı basit işlemler gerçekleştirir ve
20 parametre alan ve tüm parametreleri kullanan, ancak yalnızca
basit bir işlem. Ana program bu iki alt programı çağırmalıdır.
gram çok sayıda. Program zamanlama koduna dahil edin
iki alt programın her birine yapılan çağrıların çalışma süresini çıktılayın. Çalıştırmak
RISC makinesindeki ve CISC makinesindeki programı ve karşılaştırın
iki alt programın gerektirdiği sürenin oranları. Göre
sonuçlar, parametre geçiş hızı hakkında ne söyleyebilirsiniz?
iki makine?

Sayfa 493
Bu sayfa bilerek boş bırakılmıştır

Sayfa 494
473
11.1 Soyutlama Kavramı
11.2 Veri Soyutlamaya Giriş
11.3 Soyut Veri Tipleri için Tasarım Sorunları
11.4 Dil Örnekleri
11.5 Parametreli Soyut Veri Tipleri
11.6 Kapsülleme Yapıları
11.7 Kapsüllemeleri Adlandırma
11
Soyut Veri Tipleri ve
Kapsülleme Yapıları

Sayfa 495
474
Bölüm 11 Soyut Veri Tipleri ve Kapsülleme Yapıları
Ben n bu bölümde, biz dil yapıları destek verisi olduğunu programlama keşfetmek
soyutlama. Programlama yönteminde son 50 yılın yeni fikirleri arasında
odolojiler ve programlama dili tasarımı, veri soyutlama bunlardan biridir.
en derin.
Programlamada genel soyutlama kavramını tartışarak başlıyoruz ve
Programlama dilleri. Veri soyutlaması daha sonra tanımlanır ve bir
örnek. Bu konuyu, veri soyutlama desteğinin açıklamaları takip eder.
Ada, C++, Objective-C, Java, C# ve Ruby. Benzerlikleri ve farklılıkları aydınlatmak için
veri soyutlamayı destekleyen dil olanaklarının tasarımındaki
aynı örnek veri soyutlamasının açıklamaları Ada, C++, Objective-C,
Java ve Ruby. Ardından, Ada, C++, Java 5.0 ve C# 2005'in
parametreli soyut veri türleri tartışılır.
Bu bölümde kavramları ve yapıları göstermek için kullanılan tüm diller
soyut veri türlerinin çoğu nesne yönelimli programlamayı destekler. Bunun nedeni, erdem-
müttefik tüm çağdaş diller nesne yönelimli programlamayı destekler ve neredeyse tüm
Soyut veri türlerini desteklemeyen ve henüz destekleyenlerin çoğu belirsizliğe dönüştü.
Soyut veri türlerini destekleyen yapılar, verilerin kapsüllenmesidir ve
türündeki nesneler üzerinde işlemler. Birden çok tür içeren kapsüllemeler
daha büyük programların inşası için gereklidir. Bu kapsüllemeler ve asso-
belirtilen ad alanı sorunları da bu bölümde tartışılmaktadır.
Bazı programlama dilleri, fiziksel yerine mantıksal çerçevelemeyi destekler.
aslında isimleri kapsüllemek için kullanılan sulations. bunlar şurada tartışılıyor
Bölüm 11.7.
11.1 Soyutlama Kavramı
Bir soyutlama , yalnızca aşağıdakileri içeren bir varlığın görünümü veya temsilidir.
en önemli nitelikler. Genel anlamda soyutlama, kişinin
varlıkların örnekleri, ortak niteliklerinin olması gerekmeyen gruplara ayrılır.
düşünülen. Örneğin, kuşları yaratıklar olarak şu şekilde tanımladığımızı varsayalım:
nitelikler: iki kanat, iki bacak, bir kuyruk ve tüyler. O zaman karga bir kargadır dersek
kuş, bir karga tanımının bu özellikleri içermesi gerekmez. aynısı doğrudur
ardıç kuşları, serçeler ve sarı karınlı sapıklar için. Bu ortak özellikler
belirli kuş türlerinin açıklamalarında soyutlanabilir, çünkü hepsi
türler var. Belirli bir tür içinde, yalnızca ayırt edici nitelikler
türlerin dikkate alınması gerekir. Örneğin, kargalar varlık özelliklerine sahiptir.
siyah, belirli bir boyutta olmak ve gürültülü olmak. Bir karga ihtiyacının açıklaması
bu özellikleri sağlamak, ancak tüm kuşlarda ortak olan diğerlerini değil. Bu
Spesifikasyon üyelerinin tanımlarının önemli ölçüde basitleştirilmesiyle sonuçlanır.
şehirler. Bir türün, bir kuşun daha az soyut bir görünümü,
sadece özel niteliklerden ziyade daha yüksek düzeyde ayrıntı görmek gereklidir.
Programlama dilleri dünyasında soyutlama, buna karşı bir silahtır.
programlamanın karmaşıklığı; amacı programlamayı basitleştirmek
işlem. Etkili bir silahtır çünkü programcıların odaklanmasına izin verir.
temel nitelikler, alt nitelikleri göz ardı ederken.

Sayfa 496
11.2 Veri Soyutlamaya Giriş 475
Çağdaş programlamada iki temel soyutlama türü
diller süreç soyutlaması ve veri soyutlamasıdır.
Süreç soyutlama kavramı, programlamadaki en eski kavramlardan biridir.
dil tasarımı (1940'larda Plankalkül destekli süreç soyutlaması). Herşey
alt programlar, bir program için bir yol sağladıkları için süreç soyutlamalarıdır.
Görevini nasıl gerçekleştirdiğinin ayrıntılarını vermeden bir süreci belirtmek
(en azından arama programında). Örneğin, bir programın bir sıralama yapması gerektiğinde
bir tür sayısal veri dizisi, genellikle sıralama için bir alt program kullanır
işlem. Sıralama işleminin gerekli olduğu noktada aşağıdaki gibi bir ifade
sortInt(liste, listeLen)
programa yerleştirilir. Bu çağrı, gerçek sıralama pro-
algoritması belirtilmemiş cess. Çağrı algoritmadan bağımsızdır
adı verilen alt programda uygulanır.
sortInt alt programı durumunda , yalnızca temel nitelikler şunlardır:
sıralanacak dizinin adı, öğelerinin türü, dizinin uzunluğu,
ve sortInt çağrısının dizinin sıralanmasına neden olacağı gerçeği .
sortInt'in uyguladığı özel algoritma, olmayan bir özniteliktir.
kullanıcı için esastır. Kullanıcının yalnızca sunucunun adını ve protokolünü görmesi gerekir.
kullanabilmek için alt programı sıralamak.
Veri soyutlamanın yaygın kullanımı, zorunlu olarak sürecinkini izledi.
soyutlama, çünkü her veri soyutlamasının ayrılmaz ve temel bir parçası, onun
süreç soyutlamaları olarak tanımlanan işlemler.
11.2 Veri Soyutlamaya Giriş
Veri soyutlamanın evrimi, 1960 yılında, veri soyutlamanın ilk versiyonuyla başladı.
Kayıt veri yapısını içeren COBOL. 1 C-tabanlı diller
aynı zamanda kayıt olan yapılara sahiptir. Soyut bir veri türü, bir veri yapısıdır.
bir kayıt biçimindedir, ancak verilerini işleyen alt programları içerir.
Sözdizimsel olarak, soyut bir veri türü, yalnızca
belirli bir veri tipinin veri temsili ve sağlayan alt programlar
bu tür için işlemler. Erişim kontrolleri sayesinde gereksiz ayrıntılar
tip, tipi kullanan muhafazanın dışındaki birimlerden gizlenebilir.
Soyut bir veri tipi kullanan program birimleri, o tipteki değişkenleri bildirebilir,
gerçek temsil onlardan gizlenmiş olsa bile. Bir örneği
soyut veri türüne nesne denir .
Veri soyutlamaya yönelik motivasyonlardan biri, sürecinkine benzer.
soyutlama. Karmaşıklığa karşı bir silahtır; büyük yapma ve/veya
karmaşık programlar daha kolay yönetilebilir. Diğer motivasyonlar ve avantajlar
soyut veri türleri bu bölümde daha sonra tartışılacaktır.
1. Bölüm 2'den bir kaydın, adları olan alanları depolayan bir veri yapısı olduğunu hatırlayın.
ve farklı türlerde olabilir.

Sayfa 497
476
Bölüm 11 Soyut Veri Tipleri ve Kapsülleme Yapıları
Bölüm 12'de açıklanan nesne yönelimli programlama,
yazılım geliştirmede veri soyutlama kullanımının büyümesi ve veri
soyutlama temel bileşenlerinden biridir.
11.2.1 Soyut Veri Türü Olarak Kayan Nokta
En azından yerleşik türler açısından soyut bir veri türü kavramı,
yeni bir gelişme değil. Tüm yerleşik veri türleri, hatta Fortran I'inkiler bile,
soyut veri türleri, nadiren böyle adlandırılsalar da. Örneğin, düşünün
kayan nokta veri türü. Çoğu programlama dili en az bir
bunların. Kayan nokta türü, depolamak için değişkenler oluşturmanın araçlarını sağlar.
kayan nokta verileri ve ayrıca manipüle için bir dizi aritmetik işlem sağlar.
türün kalıcı nesneleri.
Üst düzey dillerdeki kayan nokta türleri, verilerde anahtar bir kavram kullanır
soyutlama: bilgi gizleme. Kayan nokta verilerinin gerçek biçimi
bir bellek hücresindeki değer, kullanıcıdan gizlenir ve mevcut olan tek işlem
dil tarafından sağlananlardır. Kullanıcının oluşturmasına izin verilmiyor
kullanılarak oluşturulabilenler dışında, türdeki veriler üzerinde yeni işlemler
yerleşik işlemler. Kullanıcı, ürünün parçalarını doğrudan manipüle edemez.
değerlerin gerçek temsili çünkü bu temsil gizlidir. O bu
belirli bir uygulamanın uygulamaları arasında program taşınabilirliğine izin veren özellik
dil, uygulamalar farklı temsiller kullanabilse de
belirli veri türleri için. Örneğin, IEEE 754 standardından önce kayan-
nokta temsilleri 1980'lerin ortalarında ortaya çıktı, birkaç farklı
Farklı bilgisayar mimarileri tarafından kullanılan temsiller. ama, bu
varyasyon, kayan nokta türlerini kullanan programların
çeşitli mimariler arasında taşınabilir.
11.2.2 Kullanıcı Tanımlı Soyut Veri Tipleri
Kullanıcı tanımlı bir soyut veri türü, aşağıdakilerle aynı özellikleri sağlamalıdır:
kayan nokta türü gibi dil tanımlı türler: (1) bir tür tanımı
program birimlerinin türdeki değişkenleri bildirmesine izin veren ancak
türün nesnelerinin temsili; ve (2) manipüle etmek için bir dizi operasyon
türündeki nesneler.
Artık resmi olarak kullanıcı tanımlı bağlam bağlamında soyut bir veri türü tanımlıyoruz.
türleri. Bir soyut veri türü veri bu biri aşağıdaki koşulları aşağıdaki gibidir:
• Türün nesnelerinin gösterimi program birimlerinden gizlenir
türünü kullanan, bu nedenle bu nesneler üzerinde mümkün olan tek doğrudan işlemler
türün tanımında sağlananlar.
• Nesneler üzerindeki işlemlerin türü ve protokolleri bildirimleri
türün arabirimini sağlayan türün, tek bir
sözdizimsel birim. Türün arayüzü temsile bağlı değildir
nesnelerin veya işlemlerin uygulanması. Ayrıca diğer program
birimlerin tanımlanan türde değişkenler oluşturmasına izin verilir.

Sayfa 498
11.2 Veri Soyutlamaya Giriş 477
Bilgi gizlemenin çeşitli faydaları vardır. Bunlardan biri artırılmış
güvenilirlik. Belirli bir soyut veri tipini kullanan program birimlerine cli-
bu tip entler . Müşteriler, aşağıdakilerin temel temsillerini manipüle edemezler.
Nesneleri doğrudan, kasıtlı olarak veya kazayla, böylece bütünlüğü arttırır
bu tür nesnelerden. Nesneler yalnızca sağlanan işlemler aracılığıyla değiştirilebilir.
Bilgi gizlemenin bir başka faydası da kod aralığını ve
Bir programcının yazarken veya yazarken farkında olması gereken değişken sayısı
Programın bir bölümünü okumak. Belirli bir değişkenin değeri yalnızca
sınırlı bir aralıkta kod tarafından değiştirilerek kodun anlaşılmasını kolaylaştırır
ve yanlış değişikliklerin kaynaklarını bulmak daha az zor.
Bilgi gizleme aynı zamanda ad çakışmalarını daha az olası hale getirir, çünkü kapsam
değişkenlerden daha küçüktür.
Son olarak, bilgi gizlemenin aşağıdaki avantajını göz önünde bulundurun:
yığın soyutlamasının orijinal uygulamasının bağlantılı bir liste temsilcisi kullandığını
kızgınlık. Daha sonra, bellek yönetimi sorunları nedeniyle
bu temsilde, yığın soyutlaması bitişik bir temsil kullanmak üzere değiştirilir.
resentation (bir dizide bir yığın uygulayan). Çünkü veri soyutlaması
kullanıldıysa, bu değişiklik yığın türünü tanımlayan kodda yapılabilir, ancak
yığın soyutlamasının istemcilerinin hiçbirinde herhangi bir değişiklik yapılması gerekmeyecektir. Eşit-
özellikle, örnek kodun değiştirilmesine gerek yoktur. Tabii ki, protokolde bir değişiklik
işlemlerden herhangi biri istemcilerde değişiklik gerektirecektir.
Soyut veri türlerinin tanımı, veri üyelerinin
nesneler istemcilerden gizlenmelidir, müşterilerin yapması gereken birçok durum ortaya çıkar.
bu veri üyelerine erişin. Ortak çözüm, erişimci yöntemleri sağlamaktır.
bazen alıcılar ve ayarlayıcılar olarak adlandırılır , bu da istemcilere dolaylı erişim sağlar.
gizli veriler olarak adlandırılır; bu, verileri yalnızca herkese açık hale getirmekten daha iyi bir çözümdür.
doğrudan erişim sağlayacaktır. Erişimcilerin daha iyi olmasının üç nedeni vardır:
1. Bir alıcı yöntemine sahip olmakla birlikte, yalnızca okuma erişimi sağlanabilir.
ilgili ayarlayıcı yöntemi.
2. Kısıtlamalar, ayarlayıcılara dahil edilebilir. Örneğin, eğer veri değeri
belirli bir aralıkla sınırlandırılmalıdır, ayarlayıcı bunu zorlayabilir.
3. Veri üyesinin fiili uygulaması, herhangi bir değişiklik yapılmadan değiştirilebilir.
alıcılar ve ayarlayıcılar tek erişim ise istemcileri etkiler.
Hem verileri soyut bir veri türünde genel olarak belirtmek hem de erişim sağlamak
bu veriler için sor yöntemleri, soyut veri türlerinin ilkelerinin ihlalidir.
Bazıları bunların kusurlu bir tasarımı kullanılabilir hale getiren basit boşluklar olduğuna inanıyor. Olarak
Bölüm 11.4.6.2'de göreceğimiz gibi, Ruby, örnek verilerinin herkese açık hale getirilmesine izin vermiyor. Nasıl-
Ruby, erişimci işlevleri oluşturmayı da çok kolaylaştırır. için bir meydan okumadır
geliştiriciler, tüm verilerin gerçekte gizlendiği soyut veri türleri tasarlamak için.
Türün beyanlarını paketlemenin birincil avantajı ve
işlemleri tek bir sözdizimsel birimde organize etme yöntemi sağlamasıdır.
ayrı olarak derlenebilen mantıksal birimler halinde bir program. Bazı durumlarda,
uygulama, tip bildirimine dahildir; diğer durumlarda, bu
ayrı bir sözdizimsel birimde. uygulanmasının avantajı,
türü ve farklı sözdizimsel birimlerdeki işlemleri,

Sayfa 499
478
Bölüm 11 Soyut Veri Tipleri ve Kapsülleme Yapıları
programın modülerliği ve tasarım ile uygulamanın net bir şekilde ayrılmasıdır.
tion. Hem bildirimler hem de türlerin ve işlemlerin tanımları
aynı sözdizimsel birimde, istemciden saklanmanın bazı yolları olmalı
program birimleri, tanımları belirten birimin bölümleridir.
11.2.3 Bir Örnek
Yığın, belirli sayıda veriyi depolayan, yaygın olarak uygulanabilir bir veri yapısıdır.
öğeleridir ve yalnızca uçlarından birindeki, üstteki veri öğesine erişime izin verir.
Aşağıdakileri içeren bir yığın için soyut bir veri türünün oluşturulacağını varsayalım.
soyut işlemleri düşürme:
Soyut veri türlerinin bazı uygulamalarının aşağıdakileri gerektirmediğine dikkat edin.
operasyonları oluştur ve yok et. Örneğin, sadece bir değişkeni tanımlayarak
soyut bir veri türü, altta yatan veri yapısını dolaylı olarak oluşturabilir ve
başlat. Böyle bir değişken için depolama, dolaylı olarak
değişkenin kapsamının sonu.
Yığın türündeki bir istemci, aşağıdaki gibi bir kod dizisine sahip olabilir:
. . .
oluştur(stk1);
push(stk1, color1);
push(stk1, color2);
sıcaklık = üst(stk1);
. . .
11.3 Soyut Veri Tipleri için Tasarım Sorunları
Bir dilde soyut veri türlerini tanımlamak için bir tesis, bir sözdizimi sağlamalıdır.
alt programın tip bildirimini ve prototiplerini içeren birim.
türdeki nesneler üzerinde işlemleri uygulayan gramlar. mümkün olmalı
bunları soyutlamanın müşterileri için görünür kılmak. Bu, müşterilerin beyan etmesine izin verir
soyut türün değişkenleri ve değerlerini manipüle eder. tipi olmasına rağmen
oluştur(yığın)
Bir yığın nesnesi oluşturur ve muhtemelen başlatır
yok etmek (yığın)
Yığın için depolama alanını serbest bırakır
boş(yığın)
Dönen bir yüklem (veya Boolean) işlevi
belirtilen yığın boş ve yanlış ise true
aksi halde
itme(yığın, eleman)
Belirtilen öğeyi belirtilen öğeye iter
yığın
pop(yığın)
Belirtilen öğeden üst öğeyi kaldırır
yığın
üst (yığın)
En üstteki öğenin bir kopyasını
belirtilen yığın

Sayfa 500
11.4 Dil Örnekleri 479
name dış görünürlüğe sahip olmalı, tür gösterimi gizli olmalıdır. bu
tip gösterimi ve onu uygulayan alt programların tanımları
işlemler bu sözdizimsel birimin içinde veya dışında görünebilir.
Varsa, birkaç genel yerleşik işlem aşağıdaki nesneler için sağlanmalıdır.
tür tanımıyla sağlananlar dışındaki soyut veri türleri. Orası
çok çeşitli soyut veri türleri için geçerli olan pek çok işlem değildir.
Bunlar arasında eşitlik ve eşitsizlik için atama ve karşılaştırmalar vardır. Eğer
dil, kullanıcıların atamayı aşırı yüklemesine izin vermiyor, atama işlemi
soyutlamaya dahil edilmelidir. Eşitlik ve eşitsizlik karşılaştırmaları,
bazı durumlarda soyutlamada önceden tanımlanmış olabilir, ancak diğerlerinde tanımlanamaz. örneğin, eğer
tür bir işaretçi olarak uygulanır, eşitlik işaretçi eşitliği anlamına gelebilir, ancak
tasarımcı, işaretçiler tarafından başvurulan yapıların eşitliği anlamına gelmesini isteyebilir.
Bazı işlemler birçok soyut veri türü için gereklidir, ancak bunlar
evrensel değildir, genellikle türün tasarımcısı tarafından sağlanmalıdır. Arasında
bunlar yineleyiciler, erişimciler, oluşturucular ve yıkıcılardır. Yineleyiciler tartışıldı
Bölüm 8'de. Erişimciler, doğrudan erişimden gizlenen verilere bir erişim biçimi sağlar.
istemciler tarafından erişim. Oluşturucular, yeni oluşturulan nesnelerin parçalarını başlatmak için kullanılır.
Yıkıcılar, genellikle, parçaların bir kısmı tarafından kullanılabilecek yığın depolamayı geri kazanmak için kullanılır.
örtük depolama ıslahı yapmayan dillerdeki soyut veri türü nesneleri.
Daha önce belirtildiği gibi, soyut bir veri tipinin kapsamı, tek bir veri tipini tanımlar.
veri türü ve işlemleri. C++ dahil birçok çağdaş dil,
Objective-C, Java ve C#, doğrudan soyut veri türlerini destekler. Bir alterna-
yaklaşım, daha genelleştirilmiş bir kapsülleme yapısı sağlamaktır.
herhangi biri seçici olarak belirtilebilen herhangi bir sayıda varlığı tanımlayın
muhafaza ünitesinin dışında görünür. Ada bu yaklaşımı kullanır. Bu muhafazalar
soyut veri türleri değil, soyut veri türlerinin genellemeleridir. Olarak
bu şekilde, soyut veri türlerini tanımlamak için kullanılabilirler. Ada'yı tartışsak da
bu bölümde kapsülleme yapısı, biz onu minimal bir kapsülleme olarak ele alıyoruz
tek veri türleri için. Genelleştirilmiş kapsüllemeler Bölüm 11.6'nın konusudur.
Bu nedenle, soyut veri türleri için ilk tasarım sorunu, kapsayıcının biçimidir.
tipine arayüz için. İkinci tasarım sorunu, soyut verilerin olup olmadığıdır.
türleri parametrelendirilebilir. Örneğin, dil parametreyi destekliyorsa-
soyut veri türleri, bazı yapılar için soyut bir veri türü tasarlanabilir.
her türden öğeyi depolayabilen bir yapı. Parametreli soyut veri türleri
Bölüm 11.5'te tartışılmaktadır. Üçüncü tasarım sorunu, erişim kontrollerinin ne olduğudur.
sağlandığı ve bu kontrollerin nasıl belirlendiği. Son olarak, dil tasarımcısı
tipin spesifikasyonunun fiziksel olarak ondan ayrı olup olmadığına karar vermelidir.
uygulama (veya bunun bir geliştirici seçimi olup olmadığı).
11.4 Dil Örnekleri
Veri soyutlama kavramının kökenleri SIMULA 67'ye dayanmaktadır.
dil, soyut veri türleri için tam destek sağlamadı, çünkü
uygulama ayrıntılarını gizlemenin bir yolunu içermiyordu. Bu bölümde, biz
Ada, C++, Objective-C tarafından sağlanan veri soyutlama desteğini açıklayın,
Java, C# ve Ruby.

Sayfa 501
röportaj yapmak
C++: Doğuşu, Her Yerde Bulunması,
ve Ortak Eleştiriler
BJARNE STROUSTRUP
Bjarne Stroustrup, C++'ın tasarımcısı ve orijinal uygulayıcısı ve yazarıdır.
C++ Programlama Dilinin Tarihi ve C++'ın Tasarımı ve Evrimi. Onun
araştırma ilgi alanları arasında dağıtık sistemler, simülasyon, tasarım, programlama ve
Programlama dilleri. Dr. Stroustrup, Mühendislik Fakültesi Profesörüdür.
Texas A&M Üniversitesi'nde Bilgisayar Bilimi. ANSI/ISO'da aktif olarak yer almaktadır.
C++ standardizasyonu. AT&T'de yirmi yılı aşkın bir sürenin ardından,
AT&T Labs, Bilgi ve Yazılım Sistemleri üyesi olarak araştırma yapıyor
Araştırma Laboratuvarı ACM Üyesi, AT&T Bell Laboratuvarları Üyesi ve
AT&T Üyesi. 1993 yılında Stroustrup, ACM Grace Murray Hopper Ödülü'nü aldı.
“C++ programlama dilinin temellerini atan ilk çalışmaları için. Temelli
temelleri ve Dr. Stroustrup'un devam eden çabaları üzerine C++,
bilgi işlem tarihindeki en etkili programlama dilleri.”
KISA BİR GEÇMİŞİNİZ VE BİLGİSAYAR
Senden önce ne üzerinde ve nerede çalışıyordun?
1980'lerin başında Bell Labs'a katıldınız mı? Bell Laboratuvarlarında,
Dağıtılmış genel alanda araştırma yapıyordum
sistemler. 1979'da katıldım. Ondan önce bitiriyordum
benim doktoram Cambridge Üniversitesi'nde bu alanda.
Hemen “C with Classes”a mı başladınız?
(hangisi daha sonra C++ olur)? üzerinde çalıştım
önce dağıtılmış bilgi işlemle ilgili birkaç proje
C'den Classes ile başlayarak ve geliştirme sırasında
bunun ve C++'ın. Örneğin, bir bulmaya çalışıyordum.
UNIX çekirdeğini birkaç şirkete dağıtmanın yolu
ve birçok projenin simülatörler oluşturmasına yardımcı oldu.
Seni çeken şey matematiğe olan ilgi miydi?
bu mesleğe? bir derece için kaydoldum
“bilgisayar bilimi ile matematik” ve benim mast-
ter derecesi resmen bir matematik derecesidir. ben—yanlışlıkla—
bilgi işlemin bir tür uygulamalı olduğunu düşündü
matematik. Birkaç yıl matematik yaptım ve kendime bir puan verdim.
zavallı matematikçi, ama bu hala ondan çok daha iyi
matematik bilmemek. Kaydolduğum zaman, hiç
Hatta bir bilgisayar gördüm. Bilgisayarla ilgili sevdiğim şey
daha matematiksel olmaktan ziyade programlama
alanlar.
BAŞARILI BİR DİLİ İNCELEME
Bazı öğeleri listeleyerek geriye doğru çalışmak istiyorum.
C++'ı her yerde yaygınlaştırmayı düşünün ve tepkinizi alın
tion. “Açık kaynak”tır, tescilli değildir ve
ANSI/ISO tarafından standartlaştırılmıştır. ISO C++ standardı
önemli. Bağımsız olarak geliştirilmiş birçok
ve gelişen C++ uygulamaları. standart olmadan
uymaları ve yardımcı olacak bir standart süreci
bir lehçeler kaosu olan C++'ın evrimini koordine etmek
patlayacaktı.
Her ikisinin de açık kaynak kodlu olması da önemlidir.
ve ticari uygulamalar mevcuttur. ek olarak
Birçok kullanıcı için standardın
tarafından manipülasyona karşı bir koruma önlemi sağlar.
uygulama sağlayıcıları.
ISO standartları süreci açık ve demokratiktir.
C++ komitesi nadiren 50'den az kişiyle toplanır
insanlar mevcut ve tipik olarak sekizden fazla ulus
her toplantıda temsil edilir. Bu sadece bir ven-
dors forumu.
Sistem programlama için idealdir (ki
C++ doğduğunda, pazarın en büyük sektörüydü.
ket geliştirme kodu).
Evet, C++ herhangi bir sistem için güçlü bir rakiptir-
programlama projesi Gömülü için de etkilidir
480

Sayfa 502
şu anda en hızlısı olan sistem programlama-
büyüyen sektör. C++ için başka bir büyüme alanı
yüksek performanslı sayısal/mühendislik/bilimseldir
programlama.
Nesne yönelimli doğası ve içermesi
sınıflar/kütüphaneler programlamayı daha verimli hale getirir.
zeki ve şeffaf. C++ bir çok paradigmadır
Programlama dili. Yani, birkaç destekler
temel programlama stilleri (nesne dahil
odaklı programlama) ve bunların kombinasyonları
stiller. İyi kullanıldığında bu daha temiz, daha esnek
sağlanabilecek olandan daha kolay ve verimli kitaplıklar
sadece bir paradigma kullanarak. C++ standart kitaplığı
temelde genel olan kaplar ve algoritmalar
programlama çerçevesi, bir örnektir. Kullanıldığında
(nesne yönelimli) sınıf hiyerarşileriyle birlikte,
sonuç, benzersiz bir tip güvenliği kombinasyonudur,
verimlilik ve esneklik.
AT&T geliştirme ortamında kuluçkalanması
ment. AT&T Bell Labs,
C++'ın gelişimi için çok önemliydi. Laboratuvarlar
zorlu sorunların son derece zengin bir kaynağı
ve pratik için benzersiz bir destekleyici ortam
Araştırma. C++ ile aynı araştırma laboratuvarından çıktı
C aynı entelektüel gelenekten yararlandı ve yararlandı.
deneyim, deneyim ve olağanüstü insanlar. Boyunca,
AT&T, C++ standardizasyonunu destekledi. Ancak,
C++, büyük bir pazarlamanın lehdarı değildi.
kampanya, birçok modern dil gibi. bu basitçe
laboratuvarların çalışma şekli değil.
En iyi listenizdeki herhangi bir şeyi kaçırdım mı? Şüphesiz.
Şimdi, C++ eleştirilerinden alıntı yapmama izin verin
ve tepkilerinizi alın: Çok büyük/hantal. bu
"merhaba dünya" sorunu C++'da 10 kat daha büyüktür
C. oranla C ++, kesinlikle küçük bir dil değildir
ama sonra birkaç modern dil vardır. bir dil ise
küçük, işi halletmek için büyük kütüphanelere ihtiyacınız var
ve genellikle sözleşmelere ve uzantılara güvenmek zorundadır.
Kaçınılmaz kompleksin kilit parçalarına sahip olmayı tercih ederim-
görülebileceği, öğretilebileceği ve öğretilebileceği dilde
başka bir yerde saklanmak yerine etkin bir şekilde standartlaştırılmış
bir sistemde. Çoğu amaç için C++ düşünmüyorum
hantal. C++ “merhaba dünya” programı daha büyük değil
makinemdeki C eşdeğerinden daha fazla ve olmamalı
senin olsun.
Aslında, C++ sürümünün nesne kodu
“merhaba dünya” programı C versiyonundan daha küçüktür
benim makinemde. dil neden yok
bir sürüm diğerinden daha büyük olmalıdır. hepsi bir
uygulayıcının kütüphaneleri nasıl organize ettiği sorunu.
Bir sürüm diğerinden önemli ölçüde büyükse,
sorunu daha büyük olanın uygulayıcısına bildirin
sürüm.
C++ ile programlamak daha zordur (C ile karşılaştırıldığında).
(Eleştirmenlerin söylediği bir şey.) Bir keresinde sen bile kabul et-
Vurmakla ilgili bir şeyler söyleyerek...
C'ye karşı C++ ile ayağa kalkın. evet dedim
"C" çizgisindeki bir şey, çekim yapmayı kolaylaştırır
kendini ayağında; C++ bunu zorlaştırır, ancak
yap, C++ tüm bacağını uçurur." İnsanların eğilimi
kaçırmak, C++ hakkında söylediklerimin değişen bir şey olduğudur.
tüm güçlü diller için geçerlidir. koruduğun gibi
basit tehlikelerden insanlar, kendilerini içine alırlar
yeni ve daha az belirgin problemler. kaçınan kimse
basit problemler basitçe bir değil-
çok basit biri. Çok destekleyici bir sorun ve
koruyucu ortamlar, zor problemlerin
çok geç keşfedilmek veya bir kez düzeltilmesi çok zor olmak
keşfetti. Ayrıca, nadir görülen bir sorunu bulmak, bulmaktan daha zordur.
sık bir tane çünkü ondan şüphelenmiyorsun.
Günümüzün gömülü sistemleri için uygundur.
ama günümüzün internet yazılımı için değil. C++
günümüzde gömülü sistemler için uygundur. Aynı zamanda
“İnternet yazılımı” için uygun ve yaygın olarak kullanılan
bugün. Örneğin, “C++ uygulamama bir göz atın-
"Web sayfası. Fark edeceksiniz ki, bazı önemli
Amazon, Adobe, Google gibi web servis sağlayıcıları,
Quicken ve Microsoft, kritik olarak C++'a güveniyor. oyun
yoğun C++ kullanımını bulduğunuz ilgili bir alandır.
Çok aldığın bir tane daha özledim mi? Emin.
481

Sayfa 503
482
Bölüm 11 Soyut Veri Tipleri ve Kapsülleme Yapıları
11.4.1 Ada'daki Soyut Veri Tipleri
Ada, tek bir öğeyi tanımlamak için kullanılabilecek bir kapsülleme yapısı sağlar.
temsilini gizleme yeteneği de dahil olmak üzere soyut veri türü. Ada 83 idi
soyut veri türleri için tam destek sunan ilk dillerden biridir.
11.4.1.1 Kapsülleme
Ada'daki kapsülleyici yapılara paketler denir . Bir paket olabilir
her biri paket olarak da adlandırılan iki parça. Bunlara paket denir
kapsüllemenin arayüzünü sağlayan belirtim (ve belki
daha fazlası) ve çoğunun uygulanmasını sağlayan gövde paketi , eğer
tümü değil, ilişkili paket belirtiminde belirtilen varlıkların tümü. Hepsi değil
paketlerin bir gövde kısmı vardır (yalnızca türleri ve sabitleri içine alan paketler
bedenleri yoktur veya bunlara ihtiyaç duymazlar).
Bir paket belirtimi ve ilişkili gövde paketi aynı
isim. Bir paket başlığındaki ayrılmış sözcük gövdesi , onu bir paket başlığı olarak tanımlar.
vücut paketi. Bir paket belirtimi ve gövde paketi derlenebilir
önce paket spesifikasyonunun derlenmesi şartıyla ayrı olarak. Müşteri kodu
ayrıca gövde paketi derlenmeden veya hatta yazılmadan önce derlenebilir, bunun için
konu. Bu, paket spesifikasyonu yazıldıktan sonra işin yapılabileceği anlamına gelir.
hem müşteri kodunda hem de gövde paketinde başlayın.
11.4.1.2 Bilgi Gizleme
Bir veri tipi tanımlayan bir Ada paketinin tasarımcısı,
tür tamamen istemcilere görünür veya yalnızca arabirim bilgilerini sağlar.
Elbette, temsil gizli değilse, tanımlanan tür bir
soyut veri türü. Temsili gizlemek için iki yaklaşım vardır.
paket spesifikasyonundaki müşteriler. Biri pakete iki bölüm eklemek-
yaş belirtimi—varlıkların istemciler tarafından görülebildiği ve gizlenen bir
onun içerikleri. Soyut bir veri türü için, görünür kısımda bir bildirim görünür.
spesifikasyonun sadece tipinin adını ve onun gerçeğini sağlayarak,
temsil gizlidir. Türün temsili, ekranın bir bölümünde görünür.
ayrılmış sözcük tarafından tanıtılan özel bölüm adı verilen belirtim
özel . Özel madde her zaman paket belirtiminin sonundadır.
Özel yan tümce derleyici tarafından görülebilir ancak istemci program birimleri tarafından görülmez.
Temsili gizlemenin ikinci yolu, soyut verileri tanımlamaktır.
işaretçi olarak yazın ve gövdede işaret edilen yapının tanımını sağlayın
tüm içeriği istemcilerden gizlenen paket.
Özel olduğu bildirilen türlere özel türler denir . Özel veriler
türler, atama için yerleşik işlemlere ve eşitlik için karşılaştırmalara sahiptir ve
eşitsizlik. Diğer herhangi bir işlem paket spesifikasyonunda bildirilmelidir.
bu türü tanımladı.
Paket belirtiminde bir türün temsilinin görünmesinin nedeni
hiç derleme sorunları ile ilgisi yoktur. Müşteri kodu yalnızca paketi görebilir

Sayfa 504
11.4 Dil Örnekleri 483
spesifikasyon (gövde paketi değil), ancak derleyici tahsis edebilmelidir
istemci derlenirken dışa aktarılan türdeki nesneler. Ayrıca, müşteri
yalnızca soyut veri türü için paket belirtimi olduğunda derlenebilir
derlenmiştir ve mevcuttur. Bu nedenle, derleyici caydırıcı olmalıdır.
paket belirtiminden bir nesnenin boyutunu benimseyin. Yani, temsil
türün türü derleyici tarafından görülebilmelidir, ancak istemci kodu tarafından görülmemelidir. Bu
tam olarak bir paket belirtimindeki özel madde tarafından belirtilen durum.
Özel türlere bir alternatif, daha kısıtlı bir biçimdir: sınırlı özel
türleri . İşaretçi olmayan sınırlı özel türler özel bölümde açıklanmıştır
işaretçi olmayan özel türler gibi bir paket belirtimi. Tek sözdizimsel
Fark sınırlı özel tipleri için ilan edilir ki özel sınırlı
paket spesifikasyonunun görünür kısmında. Semantik fark şu ki
sınırlı özel olarak bildirilen türdeki nesnelerin yerleşik işlemleri yoktur.
Böyle bir tür, olağan önceden tanımlanmış atama işlemleri ve
karşılaştırma anlamlı veya yararlı değildir. Örneğin, atama ve iletişim
parison yığınlar için nadiren kullanılır.
11.4.1.3 Bir Örnek
Bir yığın soyut veri türü için paket belirtimi aşağıdadır:
paket Stack_Pack (şimdiki değeri)
-- Görünür varlıklar veya genel arayüz
type Stack_Type sınırlı özeldir ;
Max_Size : sabit := 100;
fonksiyon boş (Stk: içinde Stack_Type) dönüş Boole;
prosedür itme (Stk: dışarı Stack_Type;
: Eleman Listesi ) tamsayı;
prosedür Pop (Stk: dışarı Stack_Type);
Fonksiyon : Üst (Stk içinde Stack_Type) return Integer;
-- İstemcilerden gizlenen kısım
özel
tip LIST_TYPE dizisidir (1..Max_Size) arasında bir tamsayı;
tip Stack_Type olduğunu
kayıt
Liste : Liste_Türü;
Topsub : Tamsayı aralığı 0..Max_Size := 0;
kayıt sonu ;
son Stack_Pack;
Hiçbir oluşturma veya yok etme işleminin dahil edilmediğine dikkat edin, çünkü bunlar
gerekli.
Stack_Pack için gövde paketi aşağıdaki gibidir:
ile Ada.Text_IO; Ada.Text_IO kullanın ;
paket gövdesi Stack_Pack olduğunu

Sayfa 505
484
Bölüm 11 Soyut Veri Tipleri ve Kapsülleme Yapıları
fonksiyonu Boş (Stk: in Stack_Type) dönüş Boole olduğunu
başlamak
dönüş Stk.Topsub = 0;
sonu Boş;
prosedür itme (Stk: dışarı Stack_Type;
Element: in Integer) ise
başlamak
eğer Stk.Topsub> = MAX_SIZE sonra
Put_Line("HATA - Yığın taşması");
Başka
Stk.Topsub := Stk.Topsub + 1;
Stk.List(Topsub) := Eleman;
eğer sona erer ;
son İtme;
Prosedür Pop (Stk: dışarı Stack_Type) olduğunu
başlamak
eğer Boş(Stk)
sonra Put_Line("HATA - Yığın taşması");
başka Stk.Topsub := Stk.Topsub - 1;
eğer sona erer ;
Pop'u bitir ;
fonksiyonu Üst (Stk: in Stack_Type) return tamsayı olduğu
başlamak
eğer Boş(Stk)
sonra Put_Line("HATA - Yığın boş");
başka bir dönüş Stk.List(Stk.Topsub);
eğer sona erer ;
son Üst;
son Stack_Pack;
Bu gövde paketinin kodunun ilk satırı iki madde içerir: a ile
ve bir kullanım . İle maddede dış ambalajlarda tanımlanan isimleri yapar
görünür; bu durumda giriş için işlevler sağlayan Ada.Text_IO ve
metin çıktısı. Kullanım fıkra açık yeterlilik ihtiyacını ortadan kaldırır
adlandırılmış paketteki varlıklara yapılan referansların sayısı. erişim sorunları
dış kapsüllemelere ve isim niteliklerine daha ayrıntılı olarak değinilmiştir.
Bölüm 11.7.
Gövde paketi, aşağıdaki başlıklara sahip alt program tanımlarına sahip olmalıdır:
ilgili paket spesifikasyonundaki alt program başlıklarını eşleştirin. bu
paket belirtimi, bu alt programların
ilgili gövde paketi.
Aşağıdaki yordam, Use_Stacks , Stack_Pack paketinin bir istemcisidir .
Paketin nasıl kullanılabileceğini gösterir.

Sayfa 506
11.4 Dil Örnekleri 485
ile Stack_Pack;
Stack_Pack'i kullanın ;
prosedür Use_Stacks olduğu
Topone : Tamsayı;
Yığın : Stack_Type; -- Bir Stack_Type nesnesi oluşturur
başlamak
İt (Yığın, 42);
İt (Yığın, 17);
Topone := Üst(Yığın);
Pop(Yığın);
. . .
son Use_Stacks;
Bir yığın, çoğu çağdaş dil için aptalca bir örnektir, çünkü
yığınlar için bağlantı noktası, standart sınıf kitaplıklarına dahil edilmiştir. Ancak, yığınlar
dillerin karşılaştırılmasına izin vermek için kullanabileceğimiz basit bir örnek sağlayın
bu bölümde tartışılmıştır.
11.4.1.4 Değerlendirme
Ada, Modula-2 ile birlikte destekleyen ilk ticari dildi.
soyut veri türleri. 2 Ada'nın soyut veri türleri tasarımı,
karmaşık ve tekrarlayan, açıkça gerekli olanı sağlar.
11.4.2 C++'da Soyut Veri Tipleri
İlk olarak 1985 yılında piyasaya sürülen C++, C'ye özellikler eklenerek oluşturulmuştur.
ilk önemli eklemeler, nesne yönelimli programlamayı destekleyenlerdi.
Çünkü nesne yönelimli programlamanın temel bileşenlerinden biri,
soyut veri türleri, açıkça onları desteklemek için C++ gereklidir.
Ada, soyut simüle etmek için kullanılabilecek bir kapsülleme sağlarken
veri türleri, C++ birbirine çok benzeyen iki yapı sağlar,
soyut veri türlerini daha doğrudan destekleyen sınıf ve yapı. Çünkü
yapılar en yaygın olarak yalnızca veriler dahil edildiğinde kullanılır, tartışmıyoruz
onları burada daha fazla.
C++ sınıfları türlerdir; Daha önce belirtildiği gibi Ada paketleri daha gen-
herhangi bir sayıda türü tanımlayabilen eralized kapsüllemeler. Bir program birimi
Bir Ada paketine görünürlük kazandıran herhangi bir kamu kuruluşuna erişebilir
doğrudan isimleriyle. Bir örneğini bildiren bir C++ program birimi
sınıf, o sınıftaki herhangi bir kamu varlığına da erişebilir, ancak yalnızca
sınıfın bir örneği. sağlamak için daha temiz ve daha doğrudan bir yoldur.
soyut veri türleri.
2. Ticari bir dilden ziyade akademik bir araştırma dili olan CLU dili
dil, soyut veri türlerini destekleyen ilk kişiydi.

Sayfa 507
486
Bölüm 11 Soyut Veri Tipleri ve Kapsülleme Yapıları
11.4.2.1 Kapsülleme
Bir C++ sınıfında tanımlanan verilere veri üyeleri denir ; fonksiyonlar
Bir sınıfta tanımlanan (yöntemler) üye işlevler olarak adlandırılır . Veri üyeleri ve
üye işlevler iki kategoride görünür: sınıf ve örnek. sınıf üyeleri
sınıfla ilişkilidir; örnek üyeleri örneklerle ilişkilendirilir
sınıfın. Bu bölümde, yalnızca bir sınıfın örnek üyeleri tartışılmaktadır.
Bir sınıfın tüm örnekleri, tek bir üye işlev kümesini paylaşır, ancak her biri
örneğinin, sınıfın kendi veri üyeleri kümesi vardır. Sınıf örnekleri olabilir
statik, yığın dinamik veya yığın dinamik. Statik veya yığın dinamik ise, bunlar
doğrudan değer değişkenleriyle başvurulur. Yığın dinamik ise, bunlara başvurulur
işaretçiler aracılığıyla. Yığın dinamik sınıf örnekleri her zaman
bir nesne bildiriminin detaylandırılması. Ayrıca, böyle bir sınıfın ömrü
örnek, bildiriminin kapsamının sonuna ulaşıldığında sona erer. Yığın
dinamik sınıf örnekleri yeni operatörle oluşturulur ve yeni operatörle yok edilir.
Silme operatörü. Hem yığın hem de yığın dinamik sınıfları işaretçiye sahip olabilir
yığın dinamik verilere başvuran veri üyeleri, böylece bir sınıf olsa bile
örnek yığın dinamiktir, yığına başvuran veri üyelerini içerebilir
dinamik veriler.
Bir sınıfın üye işlevi iki farklı şekilde tanımlanabilir:
tam tanım sınıfta veya yalnızca başlığında görünebilir. her ikisi de
üye işlevin üstbilgisi ve gövdesi sınıf tanımında görünür,
üye işlevi dolaylı olarak satır içine alınır. Bunun, kodunun şu anlama geldiğini hatırlayın.
normal aramayı ve geri dönüşü gerektirmek yerine arayanın koduna yerleştirilir
bağlantı süreci. Sınıfta yalnızca bir üye işlevin başlığı görünüyorsa
tanım, tam tanımı sınıfın dışında görünür ve ayrı olarak
derlenmiş. Üye işlevlerinin satır içine alınmasına izin vermenin mantığı şuydu:
gerçek zamanlı uygulamalarda fonksiyon çağrısı ek yükünü kaydetmek için
verimlilik son derece önemlidir. Satır içi üye işlevinin dezavantajı
sınıf tanımı arayüzünü karıştırarak bir azalmaya yol açmasıdır.
okunabilirlik içinde.
Üye fonksiyon tanımlarını sınıf tanımının dışına yerleştirme
spesifikasyonu uygulamadan ayırır, modernin ortak bir amacı
programlama.
11.4.2.2 Bilgi Gizleme
Bir C++ sınıfı hem gizli hem de görünür varlıkları içerebilir (yani
sınıfın istemcilerinden gizlenir veya müşteriler tarafından görülebilir). Gizlenecek varlıklar-
den özel bir maddeye yerleştirilir ve görünür veya kamuya açık varlıklar bir
kamu hükmü. Kamu fıkra nedenle sınıfa arabirimini açıklar
örnekler. 3
3. Ayrıca, aşağıdakiler bağlamında tartışılan , korunan üçüncü bir görünürlük kategorisi vardır .
Bölüm 12'deki miras.

Sayfa 508
11.4 Dil Örnekleri 487
11.4.2.3 Yapıcılar ve Yıkıcılar
C++, kullanıcının sınıf tanımlarına yapıcı işlevleri dahil etmesine izin verir.
yeni oluşturulan nesnelerin veri üyelerini başlatmak için kullanılır. Bir kurucu
işaretçi tarafından başvurulan yığın dinamik verileri de tahsis edebilir
yeni nesnenin üyeleri. Yapıcılar, bir nesne olduğunda örtük olarak çağrılır.
sınıf tipi oluşturulur. Bir kurucu, sınıfla aynı ada sahiptir.
başlattığı nesneler. Yapıcılar aşırı yüklenebilir, ancak elbette her yapı
bir sınıfın yapıcısı benzersiz bir parametre profiline sahip olmalıdır.
Bir C ++ sınıfı da adlandırılan bir fonksiyonu içerebilir yıkıcı olduğu,
sınıfın bir örneğinin ömrü sona erdiğinde örtük olarak çağrılır. Belirtildiği gibi
daha önce, yığın dinamik sınıf örnekleri, aşağıdakilere başvuran işaretçi üyeleri içerebilir:
ence yığın dinamik verileri. Böyle bir örnek için yıkıcı işlevi
yığını serbest bırakmak için işaretçi üyelerine bir silme operatörü ekleyin
referans verdikleri boşluk. Yıkıcılar genellikle bir hata ayıklama yardımcısı olarak kullanılır;
sadece nesnenin verilerinin bir kısmının veya tamamının değerlerini görüntülemeleri veya yazdırmaları durumunda
bu üyeler serbest bırakılmadan önce üyeler. Bir yıkıcının adı
sınıfın adı, önünde bir yaklaşık işareti ( ~ ).
Ne yapıcıların ne de yıkıcıların geri dönüş türleri yoktur ve hiçbiri
ifadeleri döndürür . Hem yapıcılar hem de yıkıcılar açıkça çağrılabilir.
11.4.2.4 Bir Örnek
Bir C++ soyut veri türü örneğimiz, bir kez daha bir yığındır:
#include <iostream.h>
sınıf Yığını {
private : //** Bu üyeler sadece diğer üyeler tarafından görülebilir
//** üyeler ve arkadaşlar (bkz. Bölüm 11.6.4)
int *stackPtr;
int maxLen;
int topSub;
public : //** Bu üyeler istemciler tarafından görülebilir
Stack() { //** Bir kurucu
stackPtr = yeni int [100];
maxLen = 99;
topSub = -1;
}
~Stack() { sil [] stackPtr;}; //** Bir yıkıcı
void push( int numarası) {
if (topSub == maxLen)
cerr << "Push--yığında hata dolu\n";
başka stackPtr[++topSub] = sayı;
}
geçersiz pop() {
eğer (boş())

Sayfa 509
488
Bölüm 11 Soyut Veri Tipleri ve Kapsülleme Yapıları
cerr << "Pop--yığın boşta hata\n";
başka topSub--;
}
int üst() {
eğer (boş())
cerr << "Üstteki hata - yığın boş\n";
Başka
dönüş (stackPtr[topSub]);
}
int boş() { dönüş (topSub == -1);}
}
Bu sınıf tanımının sadece birkaç yönünü tartışıyoruz çünkü gerekli değil.
kodun tüm ayrıntılarını anlamak için. Stack sınıfının nesneleri şunlardır:
yığın dinamiktir, ancak yığın dinamik verilerine başvuran bir işaretçi içerir. bu
Stack sınıfının üç veri üyesi vardır - stackPtr , maxLen ve topSub - tümü
özel olanlar. stackPtr , yığın dinamik verilerine başvurmak için kullanılır,
yığını uygulayan dizi budur. Sınıfta ayrıca dört kamu
üye işlevleri - push , pop , top ve empty - ayrıca bir kurucu ve
bir yıkıcı. Tüm üye fonksiyon tanımları bu sınıfa dahildir,
dıştan tanımlanmış olmalarına rağmen. Çünkü bedenleri
üye işlevler dahil edilmiştir, tümü örtük olarak satır içine alınmıştır. yapıcı
öbekten 100 int elemanlık bir dizi ayırmak için new operatörünü kullanır .
Ayrıca maxLen ve topSub'ı başlatır .
Aşağıdaki, Stack özet verilerini kullanan örnek bir programdır.
tip:
geçersiz ana() {
int topBir;
yığın stk; //** Stack sınıfının bir örneğini oluşturun
stk.push(42);
stk.push(17);
topOne = stk.top();
stk.pop();
. . .
}
Aşağıda, yalnızca prototiplerin bulunduğu Stack sınıfının bir tanımı verilmiştir.
üye işlevleri. Bu kod, .h dosya adıyla bir başlık dosyasında saklanır
uzantı. Üye fonksiyonların tanımları sınıf tanımını takip eder.
Bunlar , hangi sınıfı belirtmek için kapsam çözümleme operatörünü kullanır, :: ,
aittirler. Bu tanımlar, dosya adıyla bir kod dosyasında saklanır.
uzantısı .cpp .
// Stack.h - Stack sınıfı için başlık dosyası
#include <iostream.h>

Sayfa 510
11.4 Dil Örnekleri 489
sınıf Yığını {
private : //** Bu üyeler sadece diğer üyeler tarafından görülebilir
//** üyeler ve arkadaşlar (bkz. Bölüm 11.6.4)
int *stackPtr;
int maxLen;
int topSub;
halka açık:
//** Bu üyeler istemciler tarafından görülebilir
Yığın(); //** Bir kurucu
~Yığın(); //** Bir yıkıcı
geçersiz itme( int );
geçersiz pop();
int top();
int boş();
}
// Stack.cpp - Stack sınıfı için uygulama dosyası
#include <iostream.h>
#include "Stack.h"
std::cout kullanarak;
Stack::Stack() { //** Bir kurucu
stackPtr = yeni int [100];
maxLen = 99;
topSub = -1;
}
Yığın::~Yığın() { sil [] stackPtr;}; //** Bir yıkıcı
void Stack::push( int numarası) {
if (topSub == maxLen)
cerr << "Push--yığında hata dolu\n";
başka stackPtr[++topSub] = sayı;
}
geçersiz Yığın::pop() {
if (topSub == -1)
cerr << "Pop--yığın boşta hata\n";
başka topSub--;
}
int üst() {
if (topSub == -1)
cerr << "Üstteki hata - yığın boş\n";
Başka
dönüş (stackPtr[topSub]);
}
int Yığın::empty() { dönüş (topSub == -1);}

Sayfa 511
490
Bölüm 11 Soyut Veri Tipleri ve Kapsülleme Yapıları
11.4.2.5 Değerlendirme
Sınıf yapısı aracılığıyla soyut veri türleri için C++ desteği,
paketleri aracılığıyla Ada'nın ifade gücü. Her ikisi de etkili
soyut veri türlerinin kapsüllenmesi ve bilgi gizlenmesi için mekanizmalar.
Birincil fark, sınıfların tür olması, Ada paketleri ise
daha genel kapsüller. Ayrıca, Ada'nın paket yapısı
Bölüm 12'de tartışıldığı gibi, veri soyutlamadan daha fazlası için tasarlanmıştır.
11.4.3 Objective-C'deki Soyut Veri Tipleri
Daha önce belirtildiği gibi, Objective-C, başlangıçtaki C++'a benzer.
tasarım, nesne yönelimli programları destekleyen uzantılara sahip C diliydi.
ming. İkisi arasındaki temel farklardan biri, Objective-C'nin
yöntem çağrıları için Smalltalk sözdizimini kullanır.
11.4.3.1 Kapsülleme
Objective-C sınıfının arabirim kısmı, bir kapsayıcıda tanımlanır.
aşağıdaki genel sözdizimine sahip arayüz :
@interface sınıf adı : ebeveyn sınıfı {
örnek değişken bildirimleri
}
yöntem prototipleri
@son
( @ ) ile başlayan ilk ve son satırlar yönergelerdir.
Bir sınıfın uygulanması, doğal olarak adlandırılan bir kapta paketlenir.
aşağıdaki sözdizimine sahip olan uygulama :
@uygulama sınıfı-adı
yöntem tanımları
@son
C++'da olduğu gibi Objective-C sınıflarında da tipler vardır.
Yöntem prototipleri aşağıdaki sözdizimine sahiptir:
(+ | -)( dönüş türü ) yöntem adı [ : ( biçimsel parametreler ) ] ;
Varsa, artı işareti, yöntemin bir sınıf yöntemi olduğunu gösterir; a
eksi işareti bir örnek yöntemini belirtir. Resmin etrafındaki parantezler
parametreler isteğe bağlı olduklarını gösterir. Ne parantezler ne de
hiçbir parametre olmadığında kolon mevcuttur. Diğer dillerin çoğunda olduğu gibi
nesne yönelimli programlamayı destekleyen, bir Objective-C'nin tüm örnekleri
sınıf, örnek yöntemlerinin tek bir kopyasını paylaşır, ancak her örneğin kendi
örnek verilerinin kopyası.

Sayfa 512
11.4 Dil Örnekleri 491
Resmi parametre listesinin sözdizimsel biçimi, aşağıdakilerden farklıdır.
daha yaygın diller, C, C++, Java ve C#. Bir parametre varsa,
tipi, aşağıdaki gibi, parametrenin adından önce parantez içinde belirtilir.
alçaltma yöntemi prototipi:
-( void ) meth1: ( int ) x;
Bu yöntemin adı meth1: (iki nokta üst üste işaretine dikkat edin). İki parametreli bir yöntem
aşağıdaki örnek yöntem prototipinde olduğu gibi görünebilir:
-( int ) meth2: ( int ) x saniye: ( kayan nokta ) y;
Bu durumda, yöntemin adı meth2:second: olsa da, bu açıkça görülmektedir.
yanlış seçilmiş bir isim. İsmin son kısmı ( saniye ) olabilirdi
aşağıdaki gibi atlanmıştır:
-( int ) meth2: ( int ) x: ( kayan nokta ) y;
Bu durumda, yöntemin adı meth2:: şeklindedir .
Yöntem tanımları, bir
noktalı virgül yerine ayraçla ayrılmış ifade dizisi.
Parametre içermeyen bir yönteme yapılan çağrının sözdizimi aşağıdaki gibidir:
[ nesne-adı yöntem-adı ];
Bir yöntem bir parametre alırsa, yöntem adına iki nokta üst üste işareti eklenir.
ve parametre takip eder. Yöntem arasında başka noktalama işareti yok
isim ve parametre. Örneğin, üzerinde add1 adlı bir yönteme yapılan bir çağrı
bir parametre alan myAdder tarafından başvurulan nesne , bu durumda lit-
eral 7 , aşağıdaki gibi görünür:
[myAdder add1: 7];
Bir yöntem iki parametre alıyorsa ve adının yalnızca bir parçası varsa, iki nokta üst üste
ilk parametreyi takip eder ve ikinci parametre bunu takip eder. başka yok
iki parametre arasında noktalama işareti kullanılır. Daha fazla parametre varsa,
bu desen tekrarlanır. Örneğin, add1 üç parametre alırsa ve
adının başka bir parçası yok, şu şekilde çağrılabilir:
[myAdder add1: 7: 5: 3];
Bir yöntemin birden çok parametresi ve adına birden çok bölümü olabilir,
önceki örnekte olduğu gibi:
-( int ) meth2: ( int ) x saniye: ( kayan nokta ) y;
Bu yönteme örnek bir çağrı aşağıdaki gibidir:
[myObject meth2: 7 saniye: 3.2];

Sayfa 513
492
Bölüm 11 Soyut Veri Tipleri ve Kapsülleme Yapıları
Objective-C'deki yapıcılara başlatıcılar denir ; sadece giriş sağlarlar-
tial değerler. Bunlara herhangi bir ad verilebilir ve sonuç olarak açıkça belirtilmelidirler.
aranan. Yapıcılar yeni nesneye bir başvuru döndürür, bu nedenle türleri her zaman
sınıf adına bir işaretçi. self , a döndüren bir return ifadesi kullanırlar.
geçerli nesneye referans.
Objective-C'de alloc çağrılarak bir nesne oluşturulur . Genellikle, aramadan sonra-
ing alloc , sınıfın yapıcı açıkça denir. Bu iki çağrı
aşağıdaki ifadede olduğu gibi ve genellikle basamaklıdır, bu da bir
alloc ile Adder sınıfının nesnesi ve ardından yapıcısını init üzerinde çağırır .
yeni nesne ve yeni nesnenin adresini myAdder içine koyar :
Toplayıcı *myAdder = [[Adder alloc ]init];
Tüm sınıf örnekleri yığın dinamiktir ve başvuru yoluyla başvurulur
değişkenler.
C programları neredeyse her zaman giriş ve çıkış için bir başlık dosyası alır
fonksiyonlar, stdio.h . Objective-C'de, genellikle bir başlık dosyası içe aktarılır.
dahil olmak üzere, genellikle gerekli olan çeşitli işlevlerin prototiplerine sahiptir.
girdi ve çıktının yanı sıra bazı gerekli veriler için. Bu ile yapılır
Takip etmek:
# içe aktar <Vakıf/Vakıf.h>
Foundation.h başlık dosyasını içe aktarmak , pro-
gram. Bu nedenle, ana işlevin yapması gereken ilk şey , tahsis etmek ve başlatmaktır.
Bu veriler için bir depolama havuzu. Bu, aşağıdaki ifadeyle yapılır:
NSAutoreleasePool * havuz = [[NSAutoreleasePool alloc ] başlangıç];
main içindeki return ifadesinden hemen önce , bu havuz bir çağrı ile serbest bırakılır.
havuz nesnesinin tahliye yöntemi , aşağıdaki ifadede olduğu gibi:
[havuz tahliyesi];
11.4.3.2 Bilgi Gizleme
Objective-C direktiflerini kullanır @private ve @public belirtmek için
bir sınıf tanımındaki örnek değişkenlerin erişim seviyeleri. Bunlar olarak kullanılır
public ve private ayrılmış sözcükleri C++'da kullanılır. fark
Objective-C'deki varsayılanın korunduğunu, oysa C++'da özel olduğunu. farklı
nesne yönelimli programlamayı destekleyen çoğu programlama dili,
Objective-C, bir yönteme erişimi kısıtlamanın bir yolu yoktur.
Objective-C'de, kural şudur:
bir örnek değişken, değişkenin adıdır. Setter yönteminin adı
büyük harfle yazılan değişkenin adının eklendiği kelime kümesi . Yani, bir değişken için
adlandırılmış sum , alıcı yöntemine sum ve ayarlayıcı yöntemi adı verilir.

Sayfa 514
11.4 Dil Örnekleri 493
setSum olarak adlandırılacaktır . Varsayarak toplamı bir edilir int değişkeni, aşağıdaki yöntemleri
aşağıdaki gibi tanımlanabilir:
// Toplamın alıcısı
-( int ) toplam {
dönüş toplamı;
}
// Toplam için ayarlayıcı
-( void ) setSum: ( int ) s {
toplam = s;
}
Belirli bir değişken için alıcı ve ayarlayıcı yöntemi empoze etmezse
eylemleri üzerindeki herhangi bir kısıtlama, bunlar tarafından otomatik olarak oluşturulabilirler.
Objective-C derleyicisi. Bu, hangi örnek değişkenlerin listelendiğiyle yapılır.
alıcılar ve ayarlayıcılar, arayüzdeki özellik yönergesinde oluşturulacaktır.
bölümünde, aşağıdaki gibi:
@ özellik int toplamı;
Uygulama bölümünde, değişkenler bir sentez yönergesinde listelenir.
aşağıdaki gibidir:
@ sentez toplamı;
Alıcıların ve ayarlayıcıların komutlar tarafından üretildiği değişkenler.
piller genellikle özellikler olarak adlandırılır ve erişim yöntemlerinin olduğu söylenir.
sentezlenmiş .
Örnek değişkenlerin alıcıları ve ayarlayıcıları iki şekilde kullanılabilir.
sanki herkes tarafından erişilebilirmiş gibi yöntem çağrılarında veya nokta gösteriminde. İçin
örneğin, sum değişkeni için bir alıcı ve bir ayarlayıcı tanımlamışsak ,
aşağıdaki gibi kullanılabilir:
[myObject setSum: 100];
newSum = [nesnemin toplamı];
veya aşağıdakiler gibi, herkesin erişimine açıkmış gibi:
myObject.sum = 100;
newSum = myObject.sum;
11.4.3.3 Bir Örnek
Arayüzün tanımları ve yığının uygulanması aşağıdadır.
Objective-C'deki sınıf:

Sayfa 515
494
Bölüm 11 Soyut Veri Tipleri ve Kapsülleme Yapıları
// stack.m - basit bir yığının arayüzü ve uygulaması
#import <Vakıf/Vakıf.h>
// Arayüz bölümü
@interface Yığını: NSObject {
int stackArray [100];
int stackPtr;
int maxLen;
int topSub;
}
-( void ) push: (int) sayı;
-( geçersiz ) pop;
-( int ) üst;
-( int ) boş;
@son
// Uygulama bölümü
@uygulama Yığını
-(Yığın *) initWith {
maxLen = 100;
topSub = -1;
stackPtr = stackArray;
kendine dön ;
}
-( void ) push: ( int ) sayı {
if (topSub == maxLen)
NSLog(@"Push--yığında hata dolu");
Başka
stackPtr[++topSub] = sayı;
}
-( geçersiz ) pop {
if (topSub == -1)
NSLog(@"Pop--yığında hata boş");
Başka
topSub--;
}
-( int ) üst {
if (topSub >= 0)
dönüş stackPtr[topSub]);
Başka
NSLog(@"Üstteki hata--yığın boş");

Sayfa 516
11.4 Dil Örnekleri 495
}
-( int ) boş {
geri dön topSub == -1);
}
int ana ( int argc, karakter *argv[]) {
int sıcaklık;
NSAutoreleasePool *havuz = [[NSAutoreleasePool alloc ]
içinde];
Yığın *myStack = [[Stack alloc ]initWith];
[myStack push: 5];
[myStack push: 3];
temp = [myStack üst];
NSLog(@"Üst eleman:%i", temp);
[myStack açılır];
temp = [myStack üst];
NSLog(@"Üst eleman:%i", temp);
temp = [myStack üst];
[myStack açılır];
[myStack sürümü];
[havuz tahliyesi];
geri 0;
}
@son
Bu programın çıktısı aşağıdaki gibidir:
Üst öğe: 3
Üst öğe: 5
Üstte hata - yığın boş
Pop--yığın boşta hata
Bir Objective-C programından ekran çıktısı, bir çağrı ile oluşturulur.
garip görünen adı olan NSLog , kendisi olarak değişmez bir dize alan yöntem
parametre. Değişmez dizeler bir at işareti ( @ ) ve ardından bir tırnak işareti ile oluşturulur
sicim. Bir çıktı dizesi değişkenlerin değerlerini içeriyorsa,
değişkenler, NSLog çağrısına parametre olarak dahil edilir . içindeki pozisyonlar
değerler için hazır bilgi dizisi biçim kodlarıyla işaretlenmiştir, örneğin %i için
bilimsel gösterimde bir kayan nokta değeri için bir tamsayı ve %f , benzer şekilde
C'nin printf işlevine.
11.4.3.4 Değerlendirme
Objective-C'deki soyut veri türleri için destek yeterlidir. Bazıları bulur
Çok farklı iki dilden sözdizimsel formlar kullanması garip, Küçük-
talk (yöntem çağrıları için) ve C (hemen hemen her şey için). Ayrıca, onun kullanımı

Sayfa 517
496
Bölüm 11 Soyut Veri Tipleri ve Kapsülleme Yapıları
sınıf arayüzlerini belirtmek ve uygulamak için dil yapıları yerine yönergeler
mentation bölümleri de diğer programlama dillerinin çoğundan farklıdır. Bir
minör eksiklik, yöntemlere erişimi kısıtlamanın bir yolunun olmamasıdır. Yani, hatta
Yalnızca bir sınıf içinde kullanılması amaçlanan yöntemlere istemciler tarafından erişilebilir. Bir diğeri
küçük eksiklik, yapıcıların açıkça çağrılması gerektiğidir, bu nedenle
programcıların onları aramayı hatırlamalarını sağlamak ve ayrıca daha fazla dağınıklığa yol açmak
istemci programında.
11.4.4 Java'da Soyut Veri Tipleri
Soyut veri türleri için Java desteği, C++'a benzer. var, nasıl-
hiç, birkaç önemli fark. Tüm nesneler yığından ayrılır ve
referans değişkenleri aracılığıyla erişilir. Java'daki yöntemler com- tanımlanmalıdır.
kesinlikle bir sınıfta. Bir yöntem gövdesi, karşılık gelen yöntemle birlikte görünmelidir
başlık. 4 Bu nedenle, bir Java soyut veri türü, bir
tek sözdizimsel birim. Bir Java derleyicisi, aşırı olmayan herhangi bir yöntemi satır içi yapabilir.
basmış. Tanımlar, özel oldukları bildirilerek istemcilerden gizlenir.
Sınıf tanımlarında özel ve genel hükümlere sahip olmak yerine,
Java erişim değiştiricileri, yöntem ve değişken tanımlarına eklenebilir. eğer bir
örnek değişkeni veya yönteminin erişim değiştiricisi yok, paketi var
Bölüm 11.7.2'de tartışılan erişim.
11.4.4.1 Bir Örnek
Aşağıdaki, yığın örneğimiz için bir Java sınıfı tanımıdır:
sınıf YığınSınıfı {
özel int [] stackRef;
özel int maxLen,
topIndex;
public StackClass() { // Bir kurucu
stackRef = yeni int [100];
maxLen = 99;
topIndex = -1;
}
public void push( int numarası) {
if (topIndex == maxLen)
System.out.println("Basma hatası—yığın dolu");
başka stackRef[++topIndex] = sayı;
}
public void pop() {
eğer (boş())
System.out.println("Pop hatası — yığın boş");
4. Java arabirimleri bunun bir istisnasıdır—bir arabirimin yöntem başlıkları vardır ancak bunları içeremez
vücutları.

Sayfa 518
11.4 Dil Örnekleri 497
başka --topIndex;
}
public int top() {
if (boş()) {
System.out.println("Üstteki hata—yığın boş");
geri 9999;
}
Başka
dönüş (stackRef[topIndex]);
}
public boolean empty() { return (topIndex == -1);}
}
StackClass kullanan örnek bir sınıf aşağıdaki gibidir:
genel sınıf TstStack {
public static void main(String[] args) {
StackClass myStack = yeni StackClass();
myStack.push(42);
myStack.push(29);
System.out.println("29: " + myStack.top());
myStack.pop();
System.out.println("42: " + myStack.top());
myStack.pop();
myStack.pop(); // Bir hata mesajı üretir
}
}
Belirgin bir fark, Java sürümünde bir yıkıcı olmamasıdır.
Java'nın örtük çöp toplama tarafından. 5
11.4.4.2 Değerlendirme
Temel olarak bazı kozmetik yönlerden farklı olmasına rağmen, Java'nın soyut için desteği
veri türleri C++'a benzer. Java açıkça gerekli olanı sağlar
soyut veri tiplerini tasarlamak.
11.4.5 C#'da Soyut Veri Tipleri
C#'ın hem C++ hem de Java'yı temel aldığını ve bazı yeni özellikler içerdiğini hatırlayın.
yapılar. Java gibi, tüm C# sınıfı örnekleri yığın dinamiktir. Varsayılan yapı
Örnek verileri için başlangıç ​​değerleri sağlayan tors, tüm sınıflar için önceden tanımlanmıştır.
Bu oluşturucular, int türleri için 0 gibi tipik başlangıç ​​değerleri sağlar ve
boole türleri için false . Bir kullanıcı, herhangi biri için bir veya daha fazla kurucu sağlayabilir.
5. Java'da, finalize yöntemi bir tür yıkıcı işlevi görür.

Sayfa 519
498
Bölüm 11 Soyut Veri Tipleri ve Kapsülleme Yapıları
sınıfını tanımlar. Bu tür kurucular, bazılarına veya tümüne başlangıç ​​değerleri atayabilir.
sınıfın örnek verilerinin içinde başlatılmayan herhangi bir örnek değişkeni
kullanıcı tanımlı kurucuya, varsayılan kurucu tarafından bir değer atanır.
C#, yıkıcıların tanımlanmasına izin vermesine rağmen, çöp col-
yığın nesnelerinin çoğu için lection, yıkıcılar nadiren kullanılır.
11.4.5.1 Kapsülleme
Bölüm 11.4.2'de bahsedildiği gibi, C++ hem sınıfları hem de yapıları içerir.
neredeyse aynı yapılardır. Tek fark, varsayılan erişimin
sınıf için değiştirici özel yapılar için ise, kamu . C# ayrıca
yapılardır, ancak bunlar C++'ınkilerden çok farklıdır. C#'da yapılar, bir
Sense, hafif sınıflar. Yapıcılara, özelliklere, yöntemlere sahip olabilirler,
ve veri alanları ve arabirimleri uygulayabilir, ancak devralmayı desteklemez.
C#'daki yapılar ve sınıflar arasındaki bir diğer önemli fark, yapıların
referans türlerinin aksine değer türleridir. Koşarken tahsis edilirler-
yığın yerine zaman yığını. Diğerleri gibi parametre olarak iletilirlerse
değer türleri, varsayılan olarak değere göre iletilirler. Dahil olmak üzere tüm C# değer türleri
tüm ilkel türleri aslında yapılardır. Yapılar bildirilerek oluşturulabilir
int veya float gibi diğer önceden tanımlanmış değer türleri gibi . Onlarda yapabilir
onları başlatmak için bir kurucu çağıran yeni operatörle oluşturulabilir .
Yapılar, C#'da öncelikle nispeten küçük basit türleri uygulamak için kullanılır.
kalıtım için asla temel türler olması gerekmez. olduğu zaman da kullanılırlar.
ayrılan yığının aksine yığınlanacak türdeki nesneler için uygundur.
11.4.5.2 Bilgi Gizleme
C#, özel ve korumalı erişim değiştiricilerini tam olarak oldukları gibi kullanır.
Java'da kullanılır.
C#, Delphi'den miras aldığı özellikleri bir uygulama yolu olarak sağlar.
alıcıları ve ayarlayıcıları, istemci tarafından açık yöntem çağrıları gerektirmeden
ent. Objective-C'de olduğu gibi, özellikler belirli özel öğelere örtülü erişim sağlar.
örnek veri. Örneğin, aşağıdaki basit sınıf ve istemci kodunu göz önünde bulundurun:
genel sınıf Hava durumu {
public int DegreeDays { //** DegreeDays bir özelliktir
almak {
dönüş derecesiGünler;
}
set {
if ( değer < 0 || değer > 30)
Console.WriteLine(
"Değer aralık dışında: {0}", değer );
Başka
dereceGün = değer ;
}

Sayfa 520
11.4 Dil Örnekleri 499
}
özel int dereceDays;
. . .
}
. . .
Hava Durumu w = yeni Hava Durumu();
int dereceDaysToday, oldDegreeDays;
. . .
w.DereceDays = dereceDaysToday;
. . .
oldDegreeDays = w.DegreeDays;
Weather sınıfında , DegreeDays özelliği tanımlanır. Bu özellik pro-
özel veri üyesine erişim için bir alıcı yöntemi ve bir ayarlayıcı yöntem sunar,
dereceGünler . Sınıf tanımı aşağıdaki istemci kodunda, degreeDays olduğu
erişim mevcut olmasına rağmen, genel üye değişkeniymiş gibi ele alınır
sadece mülk aracılığıyla. Örtük değişken değerinin kullanımına dikkat edin .
ayarlayıcı yöntemi. Bu, mülkün yeni değerinin
referans alınır.
Yığın örneği burada C# ile gösterilmemiştir. Arasındaki tek fark
Bölüm 11.4.4.1'deki Java sürümü ve C# sürümü çıktı yöntemidir
çağrılar ve boş dönüş türü için boole yerine bool kullanımı
yöntem.
11.4.6 Ruby'de Soyut Veri Tipleri
Ruby, sınıfları aracılığıyla soyut veri türleri için destek sağlar. Açısından
yetenekleri, Ruby sınıfları C++ ve Java'dakilere benzer.
11.4.6.1 Kapsülleme
Ruby'de bir sınıf, sınıfla birlikte açılan bir bileşik ifadede tanımlanır.
ayrılmış kelime ve end ile kapatılmıştır . Örnek değişkenlerin adları
özel bir sözdizimsel biçim( @ ) ile başlamaları gerekir . Örnek meth-
ods, Ruby'deki işlevlerle aynı sözdizimine sahiptir: def ile başlarlar.
ayrılmış kelime ve end ile biter . Sınıf yöntemleri aşağıdakilerden ayırt edilir:
sınıf adının başına eklenmesiyle örnek yöntemleri
adları nokta ayırıcıyla yazılır. Örneğin, Stack adlı bir sınıfta ,
bir sınıf yönteminin adı Stack ile başlar . Ruby'deki yapıcılar
adlandırılmış başlatma . Yapıcı aşırı yüklenemeyeceğinden,
sınıf başına sadece bir tane olabilir.
Ruby'deki sınıflar, üyelerin eklenebilmesi açısından dinamiktir.
istediğin zaman. Bu, yalnızca ek sınıf tanımları dahil edilerek yapılır.
yeni üyeleri belirtin. Ayrıca, dilin önceden tanımlanmış sınıfları bile,
String gibi , genişletilebilir. Örneğin, aşağıdaki sınıfı düşünün
tanım:

Sayfa 521
500
Bölüm 11 Soyut Veri Tipleri ve Kapsülleme Yapıları
sınıf myClass
def meth1
. . .
son
son
Bu sınıf, bir ikinci yöntem eklenerek genişletilebilir MeTh2 bir saniye ile,
sınıf tanımı:
sınıf myClass
def MeTh2
. . .
son
son
Yöntemler bir sınıftan da kaldırılabilir. Bu sağlanarak yapılır
kaldırılacak yöntemin gönderildiği başka bir sınıf tanımı
parametre olarak metot remove_method . Ruby'nin dinamik sınıfları şunlardır:
bir dil tasarımcısı ticaretinin okunabilirliğine başka bir örnek (ve dolayısıyla
quence, güvenilirlik) esneklik için. Sınıflarda dinamik değişikliklere açıkça izin verilmesi
okunabilirliğe zarar verirken dile esneklik katar. belirlemek için
Bir programın belirli bir noktasındaki bir sınıfın davranışı, tüm özelliklerini bulmalıdır.
programdaki tanımları ve hepsini göz önünde bulundurun.
11.4.6.2 Bilgi Gizleme
Ruby'deki yöntemler için erişim kontrolü dinamiktir, bu nedenle erişim ihlalleri tespit edilir
sadece yürütme sırasında. Varsayılan yöntem erişimi geneldir, ancak aynı zamanda
korumalı veya özel. Erişim kontrolünü belirlemenin iki yolu vardır, her ikisi de
erişim düzeyleriyle aynı adlara sahip işlevleri kullanan, özel ve
kamu . Bunun bir yolu, uygun işlevi parametresiz çağırmaktır. Bu
sınıfta sonradan tanımlanan yöntemler için varsayılan erişimi sıfırlar. İçin
örnek,
sınıf MyClass
def meth1
. . .
son
. . .
özel
def meth7
. . .
son
. . .
sınıfın sonu MyClass

Sayfa 522
11.4 Dil Örnekleri 501
Alternatif, erişim kontrol fonksiyonlarını şu isimlerle çağırmaktır:
parametre olarak belirli yöntemler. Örneğin, aşağıdaki anlamsal olarak
önceki sınıf tanımına eşdeğer:
sınıf MyClass
def meth1
. . .
son
. . .
def meth7
. . .
son
özel :meth7, . . .
sınıfın sonu MyClass
Ruby'de bir sınıfın tüm veri üyeleri özeldir ve bu değiştirilemez.
Bu nedenle, veri üyelerine yalnızca sınıfın yöntemleriyle erişilebilir, bazıları
hangi erişimci yöntemler olabilir. Ruby'de erişilebilir örnek verileri
erişimci yöntemler aracılığıyla öznitelikler denir .
@sum adlı bir örnek değişkeni için, alıcı ve ayarlayıcı yöntemleri
aşağıdaki gibi olun:
tanım toplamı
@toplam
son
def toplamı = (new_sum)
@sum = yeni_sum
son
Alıcılara örnek değişkeninin adı eksi @ verildiğine dikkat edin . bu
setter yöntemlerinin adları, karşılık gelen alıcıların adlarıyla aynıdır,
eklenmiş bir eşittir işareti ( = ) olması dışında .
Alıcılar ve ayarlayıcılar, Ruby sistemi tarafından dolaylı olarak şu şekilde oluşturulabilir:
sınıfta sırasıyla attr_reader ve attr_writer çağrıları dahil
tanım. Bunların parametreleri, öznitelik adlarının sembolleridir,
aşağıda gösterildiği gibi:
attr_reader :toplam, :toplam
attr_writer :toplam
11.4.6.3 Bir Örnek
Ruby'de yazılmış yığın örneği aşağıdadır:
# Stack.rb - maksimum uzunlukta bir yığını tanımlar ve test eder
#
100, bir dizide uygulandı

Sayfa 523
502
Bölüm 11 Soyut Veri Tipleri ve Kapsülleme Yapıları
sınıf YığınSınıfı
# Yapıcı
def başlat
@stackRef = Array.new(100)
@maxLen = 100
@topIndex = -1
son
# itme yöntemi
def itme(sayı)
if @topIndex == @maxLen
"Push'ta hata - yığın dolu" yazıyor
Başka
@topIndex = @topIndex + 1
@stackRef[@topIndex] = sayı
son
son
# pop yöntemi
kesinlikle pop
eğer boş
"Pop'ta hata - yığın boş" yazıyor
Başka
@topIndex = @topIndex - 1
son
son
# en iyi yöntem
kesinlikle üst
eğer boş
"En üstte hata - yığın boş" yazıyor
Başka
@stackRef[@topIndex]
son
son
# boş yöntem
kesinlikle boş
@topIndex == -1
son
Yığın sınıfının # sonu
# StackClass için test kodu
myStack = StackClass.new
myStack.push(42)

Sayfa 524
11.5 Parametreli Soyut Veri Tipleri 503
myStack.push(29)
"Üst öğe (29 olmalıdır): #{myStack.top}" koyar
myStack.pop
"Üst öğe (42 olmalıdır): #{myStack.top}" koyar
myStack.pop
# Aşağıdaki pop, bir
# hata mesajı - yığın boş
myStack.pop
#{ değişken } gösteriminin , değişkenin değerini bir
dize, daha sonra göründüğü dizeye eklenir. Bu sınıf
her türden nesneyi depolayabilen bir yığın yapısı tanımlar.
11.4.6.4 Değerlendirme
Ruby'de her şeyin bir nesne olduğunu ve dizilerin aslında
nesnelere referanslar. Bu açıkça bu yığını
Ada, C++ ve Java'da benzer örnekler. Ayrıca, sadece geçerek
yapıcıya istenen maksimum uzunluk, bu sınıfın nesneleri olabilir
verilen herhangi bir maksimum uzunluk. Tabii ki, çünkü Ruby'deki diziler dinamik
uzunluk, sınıf, olmayan yığın nesnelerini uygulamak için değiştirilebilir.
makinenin bellek kapasitesi tarafından dayatılanlar dışında herhangi bir uzunlukla sınırlandırılmıştır.
ıt. Sınıf ve örnek değişkenlerin adları farklı biçimlere sahip olduğundan,
Ruby, tartışılan diğer dillere göre hafif bir okunabilirlik avantajına sahiptir
bu bölümde.
11.5 Parametreli Soyut Veri Tipleri
Soyut veri türlerini parametreleştirebilmek genellikle uygundur. Sınav için-
ple, herhangi bir veriyi depolayabilen bir yığın soyut veri türü tasarlayabilmeliyiz.
ayrı bir yığın soyut yazmak için gerekli olmak yerine skaler tipte elemanlar
her farklı skaler tip için Bunun yalnızca statik için bir sorun olduğunu unutmayın.
yazılan diller. Ruby gibi dinamik yazılmış bir dilde, herhangi bir yığın dolaylı olarak
herhangi bir tip elemanı saklayabilir. Aslında, yığının farklı öğeleri olabilir
farklı türlerde. Aşağıdaki dört alt bölümde, Ada'nın yetenekleri,
Parametreli soyut veri türleri oluşturmak için C++, Java 5.0 ve C# 2005
tartışıldı.
11.5.1 Ada
Ada'daki genel prosedürler Bölüm 9'da tartışıldı ve gösterildi.
yaşlar da genel olabilir, bu nedenle genel veya parametreli soyut oluşturabiliriz.
veri tipleri.

Sayfa 525
504
Bölüm 11 Soyut Veri Tipleri ve Kapsülleme Yapıları
Bölüm 11.4.1'de gösterilen Ada yığını soyut veri türü örneği
iki kısıtlama: (1) Türündeki yığınlar yalnızca tamsayı türündeki öğeleri depolayabilir ve
(2) yığınlar en fazla 100 elemana sahip olabilir. Bu kısıtlamaların her ikisi de
diğer için somutlaştırılabilen genel bir paket kullanılarak ortadan kaldırılabilir.
eleman türleri ve istenen herhangi bir boyut. (Bu, genel bir örneklemedir;
bir nesne oluşturmak için bir sınıfın örneklenmesinden çok farklıdır.)
paket belirtimi, genel bir yığın soyut verisinin arayüzünü tanımlar
bu özelliklerle yazın:
Genel
Max_Size : Pozitif; -- Yığın için genel bir parametre
-- boyut
tip ELEMENT_TYPE özeldir ; -- Genel bir parametre
-- eleman tipi için
paket Generic_Stack olduğunu
-- Görünür varlıklar veya genel arayüz
type Stack_Type sınırlı özeldir ;
fonksiyon boş (Stk: içinde Stack_Type) dönüş Boole;
prosedür itme (Stk: dışarı Stack_Type;
: Eleman Listesi ) ELEMENT_TYPE;
prosedür Pop (Stk: dışarı Stack_Type);
Fonksiyon : Üst (Stk içinde Stack_Type) return ELEMENT_TYPE;
-- Gizli kısım
özel
tip LIST_TYPE dizisidir (1..Max_Size) arasında ELEMENT_TYPE;
tip Stack_Type olduğunu
kayıt
Liste : Liste_Türü;
Topsub : Tamsayı aralığı 0..Max_Size := 0;
kayıt sonu ;
son Generic_Stack;
Vücut paketi Generic_Stack vücut paket ile aynıdır
Stack_Pack , Bölüm 11.4.1.3'teki Öğe türü dışında :
içinde mal parametre itin ve Üst olduğunu ELEMENT_TYPE yerine Tamsayı .
Aşağıdaki ifade , 100'lük bir yığın için Generic_Stack'i başlatır
Tamsayı türü öğeler:
paket Integer_Stack yeni Generic_Stack(100, Integer);
Float için 500 uzunluğunda bir yığın için soyut bir veri türü de oluşturulabilir.
elemanları, olduğu gibi
Float_Stack paketi yeni Generic_Stack(500, Float);
Bu örnekler, iki farklı kaynak kodu sürümü oluşturur.
Derleme zamanında Generic_Stack paketi.

Sayfa 526
11.5 Parametreli Soyut Veri Tipleri 505
11.5.2 C++
C++ ayrıca parametreli soyut veri türlerini de destekler. Örnek C++ yapmak için
Bölüm 11.4.2.4'ün yığın sınıfı, yığın boyutunda jeneriktir, yalnızca yapıcı
işlevi aşağıdaki gibi değiştirilmelidir:
Yığın ( int boyutu) {
stackPtr = yeni int [boyut];
maxLen = boyut - 1;
topSub = -1;
}
Bir yığın nesnesi için bildirim şimdi aşağıdaki gibi görünebilir:
Yığın stk(150);
Stack için sınıf tanımı her iki kurucuyu da içerebilir, böylece kullanıcılar
varsayılan boyutlu yığını kullanın veya başka bir boyut belirtin.
Yığının eleman tipi, sınıf yapılarak genel hale getirilebilir.
şablonlu bir sınıf. Ardından, eleman tipi bir şablon parametresi olabilir. bu
bir yığın türü için şablonlu sınıfın tanımı aşağıdaki gibidir:
#include <iostream.h>
şablon < typename Type> // Type, şablon parametresidir
sınıf Yığını {
özel :
*stackPtr yazın;
int maxLen;
int topSub;
kamu :
// 100 eleman yığını için bir kurucu
Yığın() {
stackPtr = yeni Tür [100];
maxLen = 99;
topSub = -1;
}
// Belirli sayıda eleman için bir kurucu
Yığın ( int boyutu) {
stackPtr = yeni Tür [boyut];
maxLen = boyut - 1;
topSub = -1;
}
~Stack() { stackPtr'yi sil ;}; // Bir yıkıcı
void push(Tip numarası) {
if (topSub == maxLen)
cout << "İletmede hata—yığın dolu\n";
başka stackPtr[++ topSub] = sayı;

Sayfa 527
506
Bölüm 11 Soyut Veri Tipleri ve Kapsülleme Yapıları
}
geçersiz pop() {
eğer (boş())
cout << "Pop'ta hata—yığın boş\n";
başka topSub --;
}
top() { yazın
eğer (boş())
cerr << "Üstteki hata - yığın boş\n";
Başka
dönüş (stackPtr[topSub]);
}
int boş() { dönüş (topSub == -1);}
}
Ada'da olduğu gibi, C++ şablonlu sınıflar, daktilo edilmiş sınıflar olacak şekilde başlatılır
derleme zamanında. Örneğin, şablonlu Stack sınıfının bir örneği de
yazılan sınıfın bir örneği olarak, aşağıdaki bildirimle oluşturulabilir:
Yığın< int > myIntStack;
Ancak, şablonlu Stack sınıfının bir örneği zaten varsa
int türü için oluşturulmuşsa , yazılan sınıfın oluşturulmasına gerek yoktur.
11.5.3 Java 5.0
Java 5.0, genel verilerin olduğu parametreli soyut veri türlerinin bir biçimini destekler.
parametreler sınıflar olmalıdır. Bunların Bölüm 9'da kısaca tartışıldığını hatırlayın.
En yaygın genel türler, LinkedList gibi koleksiyon türleridir.
ve genel destekten önce Java sınıf kitaplığında bulunan ArrayList
ic eklendi. Orijinal koleksiyon türleri , Object sınıfı örneklerini depolar , bu nedenle
herhangi bir nesneyi depolayabilirler (ancak ilkel türleri değil). Bu nedenle koleksiyon
türler her zaman birden çok türü depolayabilmiştir (sınıf oldukları sürece).
Bununla ilgili üç sorun vardı: Birincisi, her nesne kaldırıldığında
koleksiyon, uygun türe dökülmelidir. İkincisi, yoktu
koleksiyona öğeler eklendiğinde hata denetimi. Bu şu anlama geliyordu
koleksiyon oluşturulduktan sonra, herhangi bir sınıfın nesneleri, koleksiyona eklenebilir.
koleksiyonun yalnızca Integer nesnelerini depolaması amaçlanmış olsa bile . Üçüncü,
koleksiyon türleri ilkel türleri depolayamaz. Yani, int değerlerini saklamak için
bir ArrayList , değerin önce bir Integer sınıfı örneğine konması gerekiyordu . İçin
örneğin, aşağıdaki kodu göz önünde bulundurun:
//* Bir ArrayList nesnesi oluşturun
ArrayList myArray = yeni ArrayList();
//* Bir eleman oluştur
myArray.add(0, yeni Tamsayı(47));

Sayfa 528
11.5 Parametreli Soyut Veri Tipleri 507
//* İlk nesneyi al
Tamsayı myInt = (Tamsayı)myArray.get(0);
Java 5.0'da, en yaygın olarak kullanılan koleksiyon sınıfları
ArrayList , genel bir sınıf oldu. Bu tür sınıflar çağrılarak başlatılır.
sınıf yapıcısında yeni ve genel parametreyi sivri uçlu olarak iletmek
parantez. Örneğin, ArrayList sınıfı depolamak için başlatılabilir.
Aşağıdaki ifadeye sahip tamsayı nesneleri:
ArrayList <Tamsayı> myArray = new ArrayList <Tamsayı>();
Bu yeni sınıf, Java 5.0 öncesi koleksiyonlarla ilgili iki sorunun üstesinden gelir.
myArray koleksiyonuna yalnızca Tamsayı nesneleri yerleştirilebilir . Üstelik,
koleksiyondan kaldırılan bir nesneyi yayınlamaya gerek yoktur.
Java 5.0 ayrıca listeler, kuyruklar ve kümeler için koleksiyonlar için arabirimler içerir.
Kullanıcılar ayrıca Java 5.0'da genel sınıflar tanımlayabilir. Örneğin,
aşağıdakilere sahip olun:
genel sınıf Sınıfım<T> {
. . .
}
Bu sınıf aşağıdakilerle somutlaştırılabilir:
Sınıfım<Dize> myString;
Bu kullanıcı tanımlı genel sınıfların bazı dezavantajları vardır. İçin
bir şey, ilkelleri depolayamazlar. İkincisi, elemanlar olamaz
indekslendi. Öğeler, kullanıcı tanımlı genel koleksiyonlara eklenmelidir.
Eklenti yöntemi. Ardından, genel yığın örneğini bir
Dizi Listesi . Bir ArrayList'in son öğesinin kullanılarak bulunduğunu unutmayın.
boyut yapıda öğelerin sayısı ile döner yöntem.
Kaldırma yöntemi ile elemanlar yapıdan silinir . Takip et-
ing genel sınıftır:
java.util.* dosyasını içe aktarın ;
genel sınıf Stack2<T> {
özel ArrayList<T> stackRef;
özel int maxLen;
public Stack2() { // Bir kurucu
stackRef = yeni ArrayList<T> ();
maxLen = 99;
}
public void push(T newValue) {
if (stackRef.size() == maxLen)

Sayfa 529
508
Bölüm 11 Soyut Veri Tipleri ve Kapsülleme Yapıları
System.out.println("Basma hatası—yığın dolu");
Başka
stackRef.add(newValue);
}
public void pop() {
eğer (boş())
System.out.println("Pop hatası — yığın boş");
Başka
stackRef.remove(stackRef.size() - 1);
}
genel T üst() {
if (boş()) {
System.out.println("Üstteki hata—yığın boş");
boş dön;
}
Başka
dönüş (stackRef.get(stackRef.size() - 1));
}
public boolean empty() { return (stackRef.isEmpty());}
Bu sınıf , aşağıdakilerle String türü için başlatılabilir :
Stack2<String> myStack = new Stack2<String>();
Bölüm 9'dan Java 5.0'ın joker sınıfları desteklediğini hatırlayın. Sınav için-
ple, Collection<?> , tüm koleksiyon sınıfları için bir joker sınıftır. Bu izin verir
Herhangi bir koleksiyon türünü parametre olarak kabul edebilen yazılacak bir yöntem.
Bir koleksiyonun kendisi genel olabileceğinden, Collection<?> sınıfı bir
jenerik bir sınıfın jeneriğini algılayın.
Joker karakter türündeki nesnelere biraz özen gösterilmelidir. Örneğin,
çünkü bu türdeki belirli bir nesnenin bileşenleri bir türe sahiptir, diğer
type nesneleri koleksiyona eklenemez. Örneğin, düşünün
Koleksiyon<?> c = new ArrayList<String>();
Bu koleksiyona bir şey koymak için add yöntemini kullanmak yasa dışı olur.
türü String değilse .
Java 5.0'da yalnızca bir
sınırlı tipler. Örneğin, bir sınıf, genel değişkenin bir değişkenini bildirebilir.
bu değişken aracılığıyla CompareTo gibi bir yöntemi yazın ve çağırın . eğer sınıf
Bir içermez türü için örneği compareTo yöntemi
sınıf kullanılamaz. Genel bir sınıfın bir örnek için başlatılmasını önlemek için
desteklemiyorsa tip compareTo , bu aşağıdaki ile tanımlanabilir
genel parametre:
<T, Karşılaştırılabilir'i genişletir>

Sayfa 530
11.6 Kapsülleme Yapıları 509
Karşılaştırılabilir hangi arayüzüdür compareTo bildirildi. Eğer bu genel
type bir sınıf tanımında kullanılır, sınıf herhangi bir tip için başlatılamaz
Bu, Comparable öğesini uygulamaz . Ayrılmış kelimenin seçimi
uzanır garip burada görünüyor, ancak kullanımı bir alt tipi kavramına ilişkindir.
Görünüşe göre, Java tasarımcıları başka bir çağrışım eklemek istemediler.
dile ayrılmış kelime.
11.5.4 C# 2005
Java'da olduğu gibi, C# tanımlı koleksiyon sınıflarının ilk sürümü,
herhangi bir sınıfın saklanan nesneleri. Bunlar ArrayList , Stack ve Queue idi . Bunlar
sınıflar, Java 5.0 öncesi koleksiyon sınıflarıyla aynı sorunları yaşıyordu.
2005 sürümünde C#'a genel sınıflar eklendi. önceden tanımlanmış beş
genel koleksiyonlar Array , List , Stack , Queue ve Dictionary'dir (
Sözlük sınıfı, karmaları uygular). Tam olarak Java 5.0'da olduğu gibi, bu sınıflar
koleksiyonlarda karışık tiplere izin verme ve talep etme problemlerini ortadan kaldırır.
nesneler koleksiyonlardan kaldırıldığında yayınlar.
Java 5.0'da olduğu gibi, kullanıcılar C# 2005'te genel sınıflar tanımlayabilir. Bir yetenek
kullanıcı tanımlı C# jenerik koleksiyonlarından herhangi biri şu şekilde tanımlanabilir:
öğelerinin indekslenmesine izin verir (abonelik yoluyla erişilir). rağmen
dizinler genellikle tam sayılardır, bir alternatif de dizin olarak dizeleri kullanmaktır.
Java 5.0'ın C# 2005'te sağlamadığı bir yetenek joker karakterdir
sınıflar.
11.6 Kapsülleme Yapıları
Bu bölümün ilk beş bölümü, soyut veri türlerini tartışır.
minimum kapsülleme. 6 Bu bölüm, çoklu tip kapsüllemeyi açıklar.
daha büyük programlar için gerekli
11.6.1 Giriş
Bir programın boyutu birkaç bin satırı aştığında, iki uygulama
cal sorunlar belirgin hale gelir. Programcının bakış açısından,
böyle bir program, tek bir alt program koleksiyonu veya soyut veriler olarak görünür.
tip tanımları, pro-
gram entelektüel olarak yönetilebilir tutmak için. için ikinci pratik problem
daha büyük programlar yeniden derlemedir. Nispeten küçük programlar için yeniden derleme
Her değişiklikten sonra programın tamamı maliyetli değildir. Ancak büyük programlar için,
yeniden derleme maliyeti önemlidir. Yani, bulmak için bariz bir ihtiyaç var
tarafından etkilenmeyen bir programın bölümlerinin yeniden derlenmesini önlemenin yolları
6. Ada durumunda, paket enkapsülasyonu tek tipler için ve ayrıca çoklu tipler için kullanılabilir.
tipler.

Sayfa 531
510
Bölüm 11 Soyut Veri Tipleri ve Kapsülleme Yapıları
Bir değişiklik. Bu sorunların her ikisine de bariz çözüm, pro-
gramları, her biri mantıksal olarak ilişkili kod ve veri koleksiyonlarına dönüştürür.
programın geri kalanı yeniden derlenmeden derlenir. bir kapsülleme
öyle bir koleksiyondur.
Kapsüllemeler genellikle kitaplıklara yerleştirilir ve yeniden kullanım için hazır hale getirilir.
Yazıldıkları programların dışındaki programlar. İnsanlar yazıldı-
En az son 50 yıldır birkaç bin satırdan fazla olan programlar,
bu nedenle kapsülleme sağlama teknikleri bir süredir gelişmektedir.
İç içe alt programlara izin veren dillerde programlar düzenlenebilir
alt program tanımlarını mantıksal olarak daha büyük alt programların içine yerleştirerek
onları kullan. Bu Ada, Fortran 95, Python ve Ruby'de yapılabilir. Tartışıldığı gibi, anlatıldığı gibi
Bununla birlikte, Bölüm 5'te, statik kullanan programları organize etmenin bu yöntemi,
kapsam belirleme, ideal olmaktan uzaktır. Bu nedenle, iç içe alt-yayınlara izin veren dillerde bile
programlar, birincil düzenleyici kapsülleme yapısı olarak kullanılmazlar.
11.6.2 C'de Kapsülleme
C, soyut veri türleri için tam destek sağlamaz, ancak her ikisi de
soyut veri türleri ve çoklu tip kapsüllemeler simüle edilebilir.
C'de, ilgili işlevler ve veri tanımlarından oluşan bir koleksiyon,
bağımsız olarak derlenebilen bir dosya. Kütüphane görevi gören böyle bir dosya,
varlıklarının bir uygulamasına sahiptir. Dahil olmak üzere böyle bir dosyanın arayüzü
veri, tür ve işlev bildirimleri, başlık adı verilen ayrı bir dosyaya yerleştirilir.
dosya . Tip temsilleri, başlık dosyasında bildirilerek gizlenebilir.
yapı türlerine işaretçiler olarak. Bu tür yapı türlerinin tam tanımları gerekir
yalnızca uygulama dosyasında görünür. Bu yaklaşım aynı sonuca sahiptir.
Ada paketlerinde soyut veri türleri olarak işaretçilerin kullanımı olarak geri döner—yani,
işaretçilerin doğal sorunları ve atama ile olası karışıklık
ve işaretçilerin karşılaştırılması.
Kaynak biçimindeki başlık dosyası ve uygulamanın derlenmiş sürümü
mentasyon dosyası müşterilere sunulur. Böyle bir kitaplık kullanıldığında, başlık
dosyası, bir #include önişlemci özelliği kullanılarak istemci koduna dahil edilir.
tion, böylece istemci kodundaki işlevlere ve verilere yapılan başvurular şu şekilde olabilir:
kontrol. #İnclude şartname istemci olduğunu belgelemektedir
program, kitaplık uygulama dosyasına bağlıdır. Bu yaklaşım etkili
bir kapsüllemenin belirtimini ve uygulamasını ayırır.
Bu kapsüllemeler işe yarasa da, bazı güvensizlikler yaratırlar. İçin
örneğin, bir kullanıcı tanımları başlıktan kesip yapıştırabilir
#include kullanmak yerine istemci programına dosyalayın . Bu işe yarayacak,
çünkü #include işlenen dosyasının içeriğini dosyaya kopyalar.
hangi #include görünür. Ancak bununla ilgili iki sorun var
yaklaşmak. İlk olarak, istemci programının aşağıdakilere bağımlılığının belgelenmesi
kitaplık (ve başlık dosyası) kaybolur. İkincisi, kütüphanenin yazarı
başlık dosyasını ve uygulama dosyasını değiştirin, ancak istemci bunu deneyebilir
yeni uygulama dosyasını kullanmak (değiştiğini fark etmeden) ancak
kullanıcının kendi istemci programına kopyaladığı eski başlık dosyası. İçin

Sayfa 532
11.6 Kapsülleme Yapıları 511
örneğin, eski başlıkta bir x değişkeni int türü olarak tanımlanabilirdi
uygulama koduna sahip olmasına rağmen, istemci kodunun hala kullandığı dosya
x'i float olarak tanımlayan yeni başlık dosyasıyla yeniden derlendi . Böyle,
uygulama kodu int olarak x ile derlendi, ancak istemci kodu
kayan nokta olarak x ile derlendi . Bağlayıcı bu hatayı algılamaz.
Bu nedenle, hem başlığın hem de
uygulama dosyaları günceldir. Bu genellikle bir make yardımcı programı ile yapılır .
11.6.3 C++'da Kapsülleme
C++ iki farklı türde kapsülleme sağlar: başlık ve uygulama.
tion dosyaları C'deki gibi tanımlanabilir veya sınıf başlıkları ve tanımları tanımlanabilir.
C++ şablonlarının karmaşık etkileşimi ve ayrı derleme nedeniyle,
C++ şablon kitaplıklarının başlık dosyaları genellikle aşağıdakilerin tam tanımlarını içerir:
sadece veri bildirimleri ve alt program protokolleri yerine kaynaklar; bu
kısmen C++ programları için C bağlayıcısının kullanılması nedeniyle.
Kapsüllemeler için şablonsuz sınıflar kullanıldığında, sınıf başlığı
dosyası, işlev tanımlı üye işlevlerin yalnızca prototiplerine sahiptir.
Bölüm'deki son örnekte olduğu gibi, bir kod dosyasında sınıfın dışında sağlanan
11.4.2.4. Bu, arayüzü uygulamadan açıkça ayırır.
Sınıflara sahip olmaktan, ancak gen-olmamasından kaynaklanan bir dil tasarımı problemi
eralize kapsülleme yapısı, bazen işlemler tanımlandığında
iki farklı nesne sınıfı kullanan işlem, doğal olarak ait değildir.
her iki sınıfta. Örneğin, matrisler için soyut bir veri tipimiz olduğunu varsayalım.
ve bir vektörler için ve bir vektör ile bir vektör arasında bir çarpma işlemine ihtiyaç duyar.
bir matris. Çarpma kodunun veri üyelerine erişimi olmalıdır.
hem vektör hem de matris sınıfları, ancak bu sınıfların hiçbiri doğal değil
kod için ev. Ayrıca, hangisi seçilirse seçilsin, erişim
diğer üyeler bir sorundur. C++'da bu tür durumlar şunlar olabilir:
üye olmayan işlevlerin bir sınıfın "arkadaşları" olmasına izin verilerek işlenir. arkadaş
işlevlerin, bildirildikleri sınıfın özel varlıklarına erişimi vardır.
arkadaş olmak. Matris/vektör çarpma işlemi için bir C++ çözümü
işlemi hem matris hem de vektör sınıfları dışında tanımlamaktır.
ama onu her ikisinin de arkadaşı olarak tanımlayın. Aşağıdaki iskelet kodu bunu göstermektedir
senaryo:
sınıf Matrisi; //** Bir sınıf bildirimi
sınıf Vektör {
arkadaş Vektör çarpımı( const Matrix&, const Vector&);
. . .
};
class Matrix { //** Sınıf tanımı
arkadaş Vektör çarpımı( const Matrix&, const Vector&);
. . .
};
//** Hem Matrix hem de Vector nesnelerini kullanan işlev

Sayfa 533
512
Bölüm 11 Soyut Veri Tipleri ve Kapsülleme Yapıları
Vektör çarpımı( const Matrix& m1, const Vector& v1) {
. . .
}
Fonksiyonlara ek olarak, tüm sınıflar bir kişinin arkadaşları olarak tanımlanabilir.
sınıf; o zaman sınıfın tüm özel üyeleri tüm üyeler tarafından görülebilir
arkadaş sınıfından.
11.6.4 Ada Paketleri
Ada paketi özellikleri, herhangi bir sayıda veri ve alt program içerebilir
kamu ve özel bölümlerinde beyanlar. Bu nedenle, içerebilirler
herhangi bir sayıda soyut veri türü için arayüzler ve diğer herhangi bir program
Kaynaklar. Bu nedenle, paket çoklu tipte bir kapsülleme yapısıdır.
Vektör ve matrisin Bölüm 11.6.3'te açıklanan durumu göz önünde bulundurun
türleri ve her ikisinin de özel bölümlerine erişimi olan yöntemlere duyulan ihtiyaç,
arkadaş işlevleriyle C++ ile işlenir. Ada'da hem matris hem de vektör
türleri, tek bir Ada paketinde tanımlanabilir, bu da ihtiyacı ortadan kaldırır.
arkadaş işlevleri.
11.6.5 C# Derlemeleri
C#, bir sınıftan daha büyük bir kapsülleme yapısı içerir. Yapı
.NET programlama dillerinin tümü tarafından kullanılan bir dildir: Assembly. Montajlar
.NET derleyicileri tarafından oluşturulur. Bir .NET uygulaması bir veya daha fazla
meclisler. Bir montaj bir dosyadır 7 bir olmaya uygulama programlarına görünür
tek dinamik bağlantı kitaplığı ( .dll ) 8 veya bir yürütülebilir dosya ( .exe ). bir montaj
ayrı olarak geliştirilebilen bir modülü tanımlar. Bir montaj içerir
birkaç farklı bileşen. Bir montajın ana bileşenlerinden biri
bir ara dilde olan programlama kodudur.
kaynak dilinden derlenmiştir. .NET'te ara dil
Ortak Orta Düzey Dil (CIL) olarak adlandırılır. Tüm .NET ağları tarafından kullanılır.
göstergeler. Kodu CIL'de olduğundan, herhangi bir mimaride bir derleme kullanılabilir,
cihaz veya işletim sistemi. Yürütüldüğünde, CIL tam zamanında derlenir
yerleşik olduğu mimari için yerel koda.
Bir .NET derlemesi, CIL koduna ek olarak, aşağıdakileri açıklayan meta verileri içerir:
tanımladığı her sınıf ve kullandığı tüm harici sınıflar. Bir montaj da içerir
montajda referans verilen tüm montajların listesi ve montaj sürüm numarası.
7. Bir derleme herhangi bir sayıda dosyadan oluşabilir.
8. Bir dinamik bağlantı kitaplığı (DLL) , bireysel olan sınıflar ve yöntemler topluluğudur.
yürütme sırasında gerektiğinde bir yürütme programına bağlanır. Bu nedenle, bir
programın belirli bir DLL içindeki tüm kaynaklara erişimi vardır, yalnızca etkin olan kısımlar.
kullanılan müttefikler hiç yüklenir ve programa bağlanır. DLL'ler Windows'un bir parçası olmuştur
Windows ilk ortaya çıktığından beri programlama ortamı. Ancak, .NET'in DLL'leri
önceki Windows sistemlerinden oldukça farklıdır.

Sayfa 534
11.7 Kapsüllemeleri Adlandırma 513
.NET dünyasında, derleme, yazılım dağıtımının temel birimidir.
eşya. Derlemeler özel olabilir, bu durumda yalnızca bir
uygulama veya genel, yani herhangi bir uygulama bunları kullanabilir.
Daha önce belirtildiği gibi, C# bir erişim değiştiricisine sahiptir, dahili . Bir
bir sınıfın dahili üyesi, derlemedeki tüm sınıflar tarafından görülebilir.
görünüyor ki.
Java, Java Arşivi adı verilen bir derlemeye benzer bir dosya yapısına sahiptir.
( KAVANOZ). Java yazılım sistemlerinin dağıtımı için de kullanılır. JAR'lar inşa edildi
derleyici yerine Java yardımcı programı jar ile .
11.7 Kapsüllemeleri Adlandırma
Kapsüllemelerin mantıksal olarak sözdizimsel kapsayıcılar olduğunu düşündük.
ilgili yazılım kaynakları, özellikle soyut veri türleri. Amacı
bu kapsüllemeler, programları mantıksal birimler halinde organize etmenin bir yolunu sağlamaktır.
derleme için. Bu, program bölümlerinin izole edildikten sonra yeniden derlenmesini sağlar.
değişir. Yapı için gerekli olan başka bir kapsülleme türü daha vardır.
büyük programlar: bir adlandırma kapsüllemesi.
Büyük bir program genellikle birçok geliştirici tarafından yazılır ve biraz çalışır.
bağımsız olarak, hatta belki de farklı coğrafi konumlarda. Bu gerektirir
programın mantıksal birimlerinin bağımsız olması, yine de çalışabilmesi
bir arada. Aynı zamanda bir adlandırma sorunu yaratır: Bağımsız olarak nasıl çalışabilir?
geliştiriciler, değişkenleri, yöntemleri ve sınıfları için yanlışlıkla
bir program geliştiren başka bir programcı tarafından halihazırda kullanımda olan isimleri dişçi olarak kullanmak
aynı yazılım sisteminin farklı bir parçası mı?
Kütüphaneler, aynı tür adlandırma sorunlarının kaynağıdır. geçmişte
yirmi yıl, büyük yazılım sistemleri giderek daha bağımlı hale geldi
destekleyici yazılım kitaplıklarında. Hemen hemen tüm yazılımlar çağdaş dilde yazılmıştır.
programlama dilleri, büyük ve karmaşık standart kitaplıkların kullanılmasını gerektirir.
ies, uygulamaya özel kitaplıklara ek olarak. Bu yaygın kullanım çoklu
kütüphaneler, isimleri yönetmek için yeni mekanizmalar gerektirmiştir. Örneğin,
bir geliştirici mevcut bir kitaplığa yeni adlar eklediğinde veya yeni bir kitaplık oluşturduğunda,
içinde önceden tanımlanmış bir adla çelişen yeni bir ad kullanmamalıdır.
bir müşterinin uygulama programında veya başka bir kitaplıkta. biraz dil olmadan
işlemci yardımı, bu neredeyse imkansızdır, çünkü bunun için bir yol yoktur.
bir müşterinin programının hangi adları kullandığını veya hangi adların olduğunu bilmek için kitaplık yazarı
istemci programının kullanabileceği diğer kitaplıklar tarafından tanımlanır.
Adlandırma kapsüllemeleri, bunlardan kaçınmaya yardımcı olan ad kapsamlarını tanımlar.
isim çakışmaları önlemek için her kitaplık kendi adlandırma kapsüllemesini oluşturabilir.
adlarının diğer kitaplıklarda veya istemcide tanımlanan adlarla çakışmaması
kod. Bir yazılım sisteminin her mantıksal parçası, bir adlandırma kapsüllemesi oluşturabilir.
aynı amaçla.
Kapsüllemeleri adlandırma, mantıksal kapsüllemelerdir.
bitişik olması gerekmez. Birkaç farklı kod koleksiyonu yerleştirilebilir.
farklı yerlerde depolanmış olsalar bile aynı ad alanı. İçinde

Sayfa 535
514
Bölüm 11 Soyut Veri Tipleri ve Kapsülleme Yapıları
Aşağıdaki bölümlerde, kapsüllemelerin adlandırılmasının kullanımlarını kısaca açıklıyoruz.
C++, Java, Ada ve Ruby.
11.7.1 C++ Ad Alanları
C ++ bir şartname içerir ad programları yönetmenize yardımcı olur,
küresel ad alanları sorunu. Her kitaplık kendi ad alanına yerleştirilebilir
ve programdaki adları, aşağıdaki durumlarda ad alanının adıyla niteler:
adlar bu ad alanının dışında kullanılır. Örneğin, varsayalım ki bir
yığınları uygulayan soyut veri türü başlık dosyası. diye bir endişe varsa
başka bir kitaplık dosyası, yığın özet verilerinde kullanılan bir adı tanımlayabilir
yazın, yığını tanımlayan dosya kendi ad alanına yerleştirilebilir. Bu
yığın için tüm bildirimleri bir ad alanı bloğuna yerleştirerek yapılır.
aşağıdakilerde:
ad alanı myStackSpace {
// Yığın bildirimleri
}
Yığın soyut veri türü için uygulama dosyası başvuruda bulunabilir
kapsam çözümleme operatörü ile başlık dosyasında belirtilen adlar,
:: , olduğu gibi
myStackSpace::topSub
Uygulama dosyası ayrıca bir ad alanı bloğu spesifikasyonunda da görünebilir.
başlık dosyasında kullanılanla aynıdır, bu da tüm
başlık dosyasında bildirilen adlar doğrudan görünür. Bu kesinlikle daha basit, ancak
biraz daha az okunabilir, çünkü belirli bir ismin nerede olduğu daha az belirgindir.
uygulama dosyası açıklandı.
İstemci kodu, başlığın ad alanındaki adlara erişebilir
Bir kitaplığın dosyasını üç farklı şekilde. Bir yol, isimleri nitelemek
ad alanının adıyla kitaplık. Örneğin, bir referans
değişken topSub aşağıdaki gibi görünebilir:
myStackSpace::topSub
Bu, uygulama kodunun tam olarak başvuruda bulunma şeklidir.
mentation dosyası aynı ad alanında değildi.
Diğer iki yaklaşım, using yönergesini kullanır . Bu direktif olabilir
olduğu gibi, bir ad alanından tek tek adları nitelemek için kullanılır
kullanarak myStackSpace :: topSub;
hangi yapar topSub görünür, ancak herhangi bir başka isimler myStackSpace
ad alanı.

Sayfa 536
11.7 Kapsüllemeleri Adlandırma 515
Kullanarak yönergesi ayrıca a gelen bütün isimleri nitelemek için kullanılabilir
ad alanı, aşağıdaki gibi:
myStackSpace ad alanını kullanma;
Bu yönergeyi içeren kod, yönergede tanımlanan adlara doğrudan erişebilir.
ad alanı, olduğu gibi
p = üstSub;
Ad alanlarının C++'ın karmaşık bir özelliği olduğunu unutmayın.
burada hikayenin sadece en basit kısmını tanıttı.
C#, C++'ınkine çok benzeyen ad alanlarını içerir.
11.7.2 Java Paketleri
Java, bir adlandırma kapsülleme yapısı içerir: paket. Paketler
birden fazla tip 9 tanımı içerir ve bir paketteki tipler kısmidir
birbirlerinin arkadaşları. Kısmi burada bir türde tanımlanan varlıklar anlamına gelir
halka açık veya korumalı (bkz. Bölüm 12) veya erişimi olmayan bir paket
belirteç, paketteki diğer tüm türler tarafından görülebilir.
Erişim değiştiricileri olmayan varlıkların paket kapsamı olduğu söylenir , çünkü bunlar
paketin tamamında görülebilir. Java bu nedenle açık arkadaşa daha az ihtiyaç duyar
bildirimler ve C++'ın arkadaş işlevlerini veya arkadaş sınıflarını içermez.
Bir dosyada tanımlanan kaynaklar, belirli bir pakette olacak şekilde belirtilir.
olduğu gibi bir paket bildirimi ile
paket stkpkg;
Paket bildirimi, dosyanın ilk satırı olarak görünmelidir. bu
paket bildirimi içermeyen her dosyanın kaynakları örtük olarak
aynı isimsiz pakete yerleştirilir.
Bir paketin istemcileri, kullanarak pakette tanımlanan türlere başvurabilir.
tam nitelikli isimler. Örneğin, stkpkg paketinin adında bir sınıf varsa
myStack , bu sınıfa stkpkg istemcisinde stkpkg.myStack olarak başvurulabilir .
Benzer şekilde, myStack nesnesindeki topSub adlı bir değişkene başvurulabilir.
olarak stkpkg.myStack.topSub . Çünkü bu yaklaşım hızla boşalabilir-
paketler iç içe geçtiğinde rahatsız edici olan Java, içe aktarma bildirimini sağlar.
bir pakette tanımlanan adları yazmak için daha kısa referanslara izin verir. Örneğin, sup-
müşteriye poz vermek aşağıdakileri içerir:
stkpkg.myStack'i içe aktar;
Artık myStack sınıfına yalnızca adıyla başvurulabilir. Erişebilmek için
paketteki tüm tür adları, içe aktarmada bir yıldız işareti kullanılabilir
9. Burada tip derken ya bir sınıf ya da bir arayüz kastediyoruz.

Sayfa 537
516
Bölüm 11 Soyut Veri Tipleri ve Kapsülleme Yapıları
tür adı yerine deyim. Örneğin, hepsini içe aktarmak istersek
stkpkg içindeki türler için aşağıdakileri kullanabiliriz:
içe aktar stkpkg.*;
Java'nın içe aktarımının yalnızca bir kısaltma mekanizması olduğunu unutmayın. aksi halde hayır
gizli dış kaynaklar import ile sağlanır . Aslında, Java'da
derleyici veya sınıf yükleyici tarafından bulunabiliyorsa hiçbir şey örtük olarak gizlenmez
(paket adını ve CLASSPATH ortam değişkenini kullanarak).
Java'nın içe aktarımı , içinde bulunduğu paketin bağımlılıklarını belgeler.
import dosyasında adı geçen paketlerde görünür . Bu bağımlılıklar daha az
içe aktarma kullanılmadığında açıktır .
11.7.3 Ada Paketleri
Kitaplıkları kapsüllemek için sıklıkla kullanılan Ada paketleri hiyerarşik olarak tanımlanır.
saklandıkları dizin hiyerarşilerine karşılık gelen arşivler.
Örneğin, eğer subPack paketi bir çocuk olarak tanımlanan bir pakettir paketi ,
subPack kod dosyası, depolanan dizinin bir alt dizininde görünecektir.
paket paketi. Java'nın standart sınıf kitaplıkları da bir
paket hiyerarşisi ve ilgili dizin hiyerarşisinde saklanır.
Bölüm 11.4.1'de tartışıldığı gibi, paketler ad alanlarını da tanımlar. vis-
with deyimi ile bir program biriminden paket oluşturma yeteneği kazanılır . İçin
örneğin, aşağıdaki yan tümce, kaynakların ve ad alanının
Ada.Text_IO paketi mevcut.
ile Ada.Text_IO;
Ada.Text_IO'nun ad alanında tanımlanan adlara erişim kaliteli olmalıdır.
suçlandı. Örneğin, Ada.Text_IO'dan Put prosedürüne şu şekilde erişilmelidir:
Ada.Text_IO.Put
Ada.Text_IO'daki isimlere niteliksiz olarak erişmek için use yan tümcesi
olduğu gibi kullanılabilir
Ada.Text_IO kullanın ;
Bu madde ile Ada.Text_IO'dan Put prosedürüne aynı anda erişilebilir.
Put olarak katlayın . Ada'nın kullanımı Java'nın import dosyasına benzer .
11.7.4 Ruby Modülleri
Ruby sınıfları, diğer lan-
nesne yönelimli programlamayı destekleyen göstergeler. Ruby'nin ek bir özelliği var
modül adı verilen kapsülleme adlandırma . Modüller tipik olarak koleksiyonları tanımlar.

Sayfa 538
özet 517
yöntemler ve sabitler. Bu nedenle, modüller kitaplıkları kapsüllemek için uygundur
adları ayrı bir ad alanında olan ilgili yöntemler ve sabitler
modunu kullanan bir programda diğer isimlerle isim çakışması olmaz.
ule. Modüller, somutlaştırılamayan veya alt sınıflanamayan sınıflardan farklıdır.
ve değişkenleri tanımlamayın. Bir modülde tanımlanan yöntemler şunları içerir:
adlarında modülün adı. Örneğin, aşağıdaki iskeleti düşünün
modül tanımı:
modül MyStuff
PI = 3.14159265
def MyStuff.mymethod1 (p1)
. . .
son
def MyStuff.mymethod2 (p2)
. . .
son
son
MyStuff modülünün kendi dosyasında saklandığını varsayarsak,
MyStuff sabitini ve yöntemlerini kullanmak için önce
modül. Bu, dosya adını alan require yöntemiyle yapılır .
parametre olarak bir dize değişmezi biçimi. Daha sonra, sabitler ve yöntemler
modüle modülün adı üzerinden erişilebilir. Aşağıdakileri göz önünde bulundurun-
dosyada saklanan MyStuff örnek modülümüzü kullanan kod
myStuffMod adlı :
'myStuffMod' gerektirir
. . .
MyStuff.mymethod1(x)
. . .
Modüller Bölüm 12'de daha ayrıntılı olarak tartışılmaktadır.
ÖZET
Soyut veri türleri kavramı ve bunların program tasarımında kullanımı,
bir mühendislik disiplini olarak programlamanın gelişiminde bir dönüm noktasıdır.
Konsept nispeten basit olmasına rağmen, kullanımı uygun hale gelmedi.
ve diller onu destekleyecek şekilde tasarlanana kadar güvenlidir.
Soyut veri türlerinin iki temel özelliği, verilerin paketlenmesidir.
ilişkili işlemleri ve bilgi gizleme ile nesneler. Dil
soyut veri türlerini doğrudan destekleyebilir veya daha genel verilerle simüle edebilir
kapsüllemeler.
Ada, simüle etmek için kullanılabilecek paketler adı verilen kapsüllemeler sağlar.
soyut veri türleri. Paketler normalde iki bölümden oluşur:

Sayfa 539
518
Bölüm 11 Soyut Veri Tipleri ve Kapsülleme Yapıları
istemci arayüzünü ve uygulamayı sağlayan bir gövdeyi sunar
soyut veri türü. Pakette veri türü temsilleri görünebilir
belirtim, ancak müşterilerden gizli yan tümcesine koyarak gizli olun.
paket. Soyut türün kendisi, programın genel kısmında özel olarak tanımlanır.
paket özellikleri. Özel türlerin atama için yerleşik işlemleri vardır
ve eşitlik ve eşitsizlik için karşılaştırma.
C++ veri soyutlaması sınıflar tarafından sağlanır. Sınıflar türlerdir ve
örnekler yığın veya yığın dinamik olabilir. Bir üye işlevi (yöntem)
tam tanımı sınıfta görünebilir veya yalnızca proto-
sınıfta verilen col ve başka bir dosyaya yerleştirilen tanım,
ayrı derlenmiştir. C++ sınıflarında, her birinin ön eki olan iki yan tümcesi olabilir.
bir erişim değiştiricisi: özel veya genel. Hem yapıcılar hem de yıkıcılar
sınıf tanımlarında verilmelidir. Yığın tahsisli nesneler açıkça dağıtılmalıdır.
ile yer silme .
C++'da olduğu gibi, Objective-C veri soyutlamaları sınıflardır. Sınıflar türlerdir
ve hepsi yığın dinamiktir. Yöntem bildirimleri arabirim sekmesinde görünmelidir.
sınıflar ve metot tanımları uygulama bölümlerinde yer almalıdır.
Yapıcılar başlatıcılar olarak adlandırılır ; açıkça çağrılmalıdırlar. Misal
değişkenler private veya public olabilir. Yöntemlere erişim kısıtlanamaz.
Yöntem çağrıları, Smalltalk tarafından kullanılana benzer bir sözdizimi kullanır. Amaç-C
özellikleri destekler ve mülkler için erişim yöntemleri, tarafından sağlanabilir.
derleyici.
Java veri soyutlamaları, tüm Java nesneleri dışında C++ ile benzerdir.
yığından tahsis edilir ve referans değişkenler aracılığıyla erişilir.
Ayrıca, tüm nesneler çöp toplanır. Erişim değiştiricilere sahip olmak yerine
yan tümcelere eklenir, Java'da değiştiriciler bireysel bildirimlerde görünür
(veya tanımlar).
C#, hem sınıflar hem de yapılar ile soyut veri türlerini destekler. Yapıları
değer türleri ve devralmayı desteklemez. C# sınıfları Java'nınkilere benzer.
Ruby, sınıfları ile soyut veri türlerini destekler. Ruby'nin sınıfları farklıdır
dinamik oldukları için diğer dillerin çoğundan
Yürütme sırasında eklenebilir, silinebilir veya değiştirilebilir.
Ada, C++, Java 5.0 ve C# 2005, soyut veri türlerinin
parametreleştirilmiş—Ada, genel paketleri aracılığıyla, C++ şablonları aracılığıyla
sınıfları ve koleksiyon sınıfları ve arayüzleri aracılığıyla Java 5.0 ve C# ve
kullanıcı tanımlı genel sınıflar.
Büyük programların inşasını desteklemek için bazı çağdaş programlar
göstergeler, bir
mantıksal olarak ilişkili türler topluluğu. Kapsülleme ayrıca erişim sağlayabilir
kuruluşlarını kontrol eder. Kapsüllemeler, programcıya bir yöntem sağlar
yeniden derlemeyi de kolaylaştıran programların düzenlenmesi.
C++, C#, Java, Ada ve Ruby, adlandırma kapsüllemeleri sağlar. Ada için
ve Java, bunlar paketler olarak adlandırılır; C++ ve C# için ad alanlarıdır; için
Ruby, onlar modüller. Kısmen paketlerin mevcudiyeti nedeniyle, Java
arkadaş işlevleri veya arkadaş sınıfları yoktur. Ada'da paketler kullanılabilir
adlandırma kapsüllemeleri olarak.

Sayfa 540
Soruları gözden geçir 519
İNCELEME SORULARI
1. Programlama dillerinde iki tür soyutlama nedir?
2. Soyut veri tipini tanımlayın .
3. Soyut veri tanımının iki bölümünün avantajları nelerdir?
tür ?
4. Destekleyen bir dil için dil tasarımı gereksinimleri nelerdir?
soyut veri türleri?
5. Soyut veri türleri için dil tasarımı sorunları nelerdir?
6. Bir Ada paketinde bilgi gizlemenin nasıl sağlandığını açıklayın.
7. Bir Ada paketi spesifikasyonunun özel kısmı neye görünür?
8. Özel ve sınırlı özel türler arasındaki fark nedir?
Ada'da mı?
9. Ada paketi spesifikasyonunda neler var? Peki ya vücut paketi?
10. Ada with yan tümcesi ne işe yarar ?
11. Ada use maddesi ne işe yarar ?
12. C++ sınıfı ile Ada arasındaki temel fark nedir?
paket?
13. C++ nesneleri nereden tahsis edilir?
14. Bir C++ üye fonksiyonunun tanımı hangi farklı yerlerde olabilir?
belli olmak?
15. Bir C++ yapıcısının amacı nedir?
16. Bir kurucunun yasal iade türleri nelerdir?
17. Tüm Java yöntemleri nerede tanımlanır?
18. C++ sınıfı örnekleri nasıl oluşturulur?
19. Objective-C'nin arayüz ve uygulama bölümleri nasıldır?
sınıf belirtilmiş mi?
20. Objective-C sınıfları türleri midir?
21. Objective-C yöntemlerinin erişim düzeyi nedir?
22. Objective-C'deki yöntem çağrılarının sözdiziminin kaynağı nedir?
23. Yapıcılar ne zaman Objective-C'de örtük olarak çağrılır?
24. Özellikler neden bir örnek değişkeni belirtmekten daha iyidir?
halka açık?
25. Java sınıfı örnekleri nereden tahsis edilir?
26. Java'nın neden yıkıcıları yok?
27. Tüm Java yöntemleri nerede tanımlanır?
28. Java sınıfları nereye tahsis edilir?
29. Yıkıcılara neden Java'da C++'da olduğu kadar sık ​​ihtiyaç duyulmuyor?

Sayfa 541
520
Bölüm 11 Soyut Veri Tipleri ve Kapsülleme Yapıları
30. Arkadaş işlevi nedir? Arkadaş sınıfı nedir?
31. Java'nın arkadaş işlevleri veya arkadaş sınıfları olmamasının nedenlerinden biri nedir?
32. C# yapıları ve sınıfları arasındaki temel farkları tanımlayın.
33. C#'ta bir yapı nesnesi nasıl oluşturulur?
34. Özel türlere erişenlerin mak-
türlerini halka açıklar.
35. C++ yapısı ile C# yapısı arasındaki farklar nelerdir?
36. Java'nın Ada'daki gibi bir use cümleciğine neden ihtiyacı yoktur ?
37. Tüm Ruby kurucularının adı nedir?
38. Ruby ve Ruby sınıfları arasındaki temel fark nedir?
C++ ve Java'nınkiler?
39. Ada genel sınıflarının örnekleri nasıl oluşturulur?
40. C++ şablon sınıflarının örnekleri nasıl oluşturulur?
41. Büyük projelerin yapımında ortaya çıkan iki sorunu tanımlayın.
kapsülleme yapılarının geliştirilmesine yol açan gramlar.
42. Soyut veri tiplerini tanımlamak için C kullanıldığında ne gibi problemler ortaya çıkabilir?
43. C++ ad alanı nedir ve amacı nedir?
44. Java paketi nedir ve amacı nedir?
45. Bir .NET derlemesini tanımlayın.
48. Bir Ruby modülünde hangi öğeler görünebilir?
PROBLEM SETİ
1. Bazı yazılım mühendisleri, ithal edilen tüm varlıkların
dışa aktaran program biriminin adıyla nitelenir. Katılıyor musun?
Cevabınızı destekleyin.
2. Birinin bir yığın soyut veri türü tasarladığını varsayalım.
tion top, bir erişim yolu (veya işaretçi) döndürmek yerine bir erişim yolu (veya işaretçi) döndürdü.
üst öğenin kopyası. Bu gerçek bir veri soyutlaması değildir. Niye ya? Vermek
sorunu anlatan bir örnek.
3. Java paketlerinin benzerlik ve farklılıklarının bir analizini yazın.
yaşlar ve C++ ad alanları.
4. Soyut bir veri tipi tasarlamanın dezavantajları nelerdir?
Işaretçi?
5. İşaretçi olmayan soyut veri türlerinin yapısı neden
Ada paketi özellikleri?
6. Yazma erişimcisine göre C# özelliklerinin avantajlarını tartışın
C++ veya Java'daki yöntemler.

Sayfa 542
Programlama Alıştırmaları 521
7. C'nin kapsüllemeye yaklaşımının tehlikelerini açıklayın.
8. C++ neden Problem 7'de tartışılan sorunları ortadan kaldırmadı?
9. Objective-C yaklaşımının avantajları ve dezavantajları nelerdir?
sınıf yöntemlerini örnek yöntemlerden sözdizimsel olarak ayırt etmek için?
10. C++'da yöntem çağrıları hangi yönlerden daha fazla veya daha az okunabilir?
Objective-C'ninkiler?
11. Objective-C tasarımının lehine ve aleyhine olan argümanlar nelerdir?
yöntem erişimi kısıtlanamaz?
12. Yıkıcılar neden Java'da nadiren kullanılırken C++'da gereklidir?
13. C++ politikasının satır içi kullanımına ilişkin lehte ve aleyhteki argümanlar nelerdir?
yöntemler?
14. Bir C# yapısının C# sınıfına tercih edildiği bir durumu tanımlayın.
15. Kapsüllemelerin isimlendirilmesinin büyük ölçekli geliştirmeler için neden önemli olduğunu açıklayın.
programlar.
16. Bir istemcinin bir ad alanından bir ada başvurabileceği üç yolu tanımlayın
C++'da.
17. C# standart kitaplığının ad alanı System , örtük olarak değil
C# programlarında kullanılabilir. Bunun iyi bir fikir olduğunu düşünüyormusun? savunmak
Cevap.
18. Değiştirme yeteneğinin avantajları ve dezavantajları nelerdir?
Ruby'deki nesneler?
19. Java'nın paketlerini Ruby'nin modülleriyle karşılaştırın.
PROGRAMLAMAALIŞTIRMALAR
1. Bir düzlemde tamsayı elemanları olan bir matris için soyut bir veri tipi tasarlayın.
toplama, çıkarma ve
matris çarpımı.
2. Bir dilde kayan öğeler için bir kuyruk soyut veri türü tasarlayın.
Bildiğiniz gibi, kuyruğa alma, kuyruğa alma ve boşaltma işlemleri dahil. bu
kuyruktan çıkarma işlemi, öğeyi kaldırır ve değerini döndürür.
3. Bölüm 11.4.2'de gösterilen soyut yığın türü için C++ sınıfını değiştirin.
bağlantılı bir liste gösterimi kullanmak ve aynı kodla test etmek için
bu bölümde görünür.
4. Bölüm 11.4.4'te gösterilen soyut yığın türü için Java sınıfını değiştirin
bağlantılı bir liste gösterimi kullanmak ve aynı kodla test etmek için
bu bölümde görünür.
5. İşlemler de dahil olmak üzere karmaşık sayılar için soyut bir veri türü yazın
toplama, çıkarma, çarpma, bölme, çıkarma için

Sayfa 543
522
Bölüm 11 Soyut Veri Tipleri ve Kapsülleme Yapıları
karmaşık sayının bölümleri ve karmaşık sayının yapısı
iki kayan nokta sabitinden, değişkenlerinden veya ifadelerinden. Ada'yı kullan,
C++, Java, C# veya Ruby.
6. Öğeleri 10 karakter depolayan kuyruklar için soyut bir veri türü yazın
isimler. Kuyruk elemanları, dinamik olarak
yığın. Kuyruk işlemleri kuyruğa alma, kuyruğa alma ve boşaltma işlemleridir. Either "kalıbını kullanınız
Ada, C++, Java, C# veya Ruby.
7. Öğeleri herhangi bir birincil olabilen bir kuyruk için soyut bir veri türü yazın.
aktif tip. Java 5.0, C# 2005, C++ veya Ada kullanın.
8. Öğeleri her ikisini de içeren bir kuyruk için soyut bir veri türü yazın.
20 karakterlik dize ve bir tamsayı önceliği. Bu sıraya sahip olmalıdır
aşağıdaki yöntemler: bir dize ve bir tamsayı olarak alan enqueue
parametreler; olan kuyruktan dizeyi döndüren dequeue
en yüksek öncelik; ve boş. Sıra tutulmamalı
elemanlarının öncelik sırası, bu nedenle kuyruktan çıkarma işlemi her zaman
tüm kuyruğu arayın.
9. Deque, ekleme ve çıkarma işlemlerinin yapıldığı çift uçlu bir kuyruktur.
her iki uçtan da elemanlar. Çözümü Programlama Alıştırması için değiştirin
7 bir deque uygulamak.
10. Rasyonel sayılar için soyut bir veri türü yazın (bir pay ve bir
payda). Sayıyı almak için bir kurucu ve yöntemler ekleyin.
ator, payda alma, toplama, çıkarma, çarpma, bölme
sion, eşitlik testi ve görüntüleme. Java, C#, C++, Ada veya Ruby kullanın.

Sayfa 544
523
12.1 Giriş
12.2 Nesne Yönelimli Programlama
12.3 Nesne Yönelimli Diller için Tasarım Sorunları
12.4 Smalltalk'ta Nesne Yönelimli Programlama Desteği
12.5 C++'da Nesne Yönelimli Programlama Desteği
12.6 Objective-C'de Nesne Yönelimli Programlama Desteği
12.7 Java'da Nesne Yönelimli Programlama Desteği
12.8 C#'da Nesne Yönelimli Programlama Desteği
12.9 Ada 95'te Nesne Yönelimli Programlama Desteği
12.10 Ruby'de Nesne Yönelimli Programlama Desteği
12.11 Nesneye Yönelik Yapıların Uygulanması
12
Nesne Desteği-
Odaklı Programlama

Sayfa 545
524
Bölüm 12 Nesne Yönelimli Programlama Desteği
Bu bölüm, nesne yönelimli programlamaya kısa bir girişle başlamaktadır.
ardından miras için birincil tasarım konularının kapsamlı bir tartışması
tans ve dinamik bağlama. Ardından, nesne yönelimli program desteği-
Smalltalk, C++, Objective-C, Java, C#, Ada 95 ve Ruby'de ming tartışılmaktadır. bu
bölüm, dinamik bağlamaların uygulanmasına ilişkin kısa bir genel bakışla sona ermektedir.
nesne yönelimli dillerdeki yöntemlere yapılan yöntem çağrılarının sayısı.
12.1 Giriş
Nesne yönelimli programlamayı destekleyen diller artık kesin
ana akıma yerleşmiştir. COBOL'dan LISP'ye, sanal olarak dahil
aradaki her dil, nesne yönelimli programı destekleyen lehçeler-
ming ortaya çıktı. C++, Objective-C ve Ada 95, prosedürel ve
nesne yönelimli programlamaya ek olarak veri yönelimli programlama.
LISP'nin nesne yönelimli bir versiyonu olan CLOS (Paepeke, 1993), ayrıca şunları da destekler:
fonksiyonel programlama Tasarlanan yeni dillerden bazıları
nesne yönelimli programlamayı desteklemek için diğer programları desteklemeyin-
ming paradigmaları, ancak yine de bazı temel zorunluluk yapılarını kullanıyor
ve eski zorunlu dillerin görünümüne sahip. Bunların arasında
Java ve C#'dır. Ruby'yi kategorize etmek biraz zor: Bu saf bir nesne-
Tüm verilerin nesne olması anlamında yönelimli dil, ancak bir melezdir.
bu dil, prosedürel programlama için kullanılabilir. Nihayet,
saf nesne yönelimli ama biraz alışılmadık bir dil var:
Küçük konuşma. Smalltalk için tam destek sunan ilk dil oldu
nesne yönelimli programlama. Nesne yönelimli desteğin ayrıntıları
programlama diller arasında büyük farklılıklar gösterir ve bu birincil konudur
bu bölümün.
Bu bölüm ağırlıklı olarak Bölüm 11'e dayanmaktadır.
o bölümün özeti. Bu ilişki, nesne yönelimli olduğu gerçeğini yansıtır.
programlama, özünde, soyutlama ilkesinin bir uygulamasıdır.
soyut veri türleri. Spesifik olarak, nesne yönelimli programlamada, ortak-
benzer soyut veri türlerinden oluşan bir koleksiyonun niteliği, çarpanlara ayrılır ve bir
yeni tip. Koleksiyonun üyeleri, bu ortak parçaları ondan miras alır.
yeni tip. Bu özellik, nesne yönelimli yaklaşımın merkezinde yer alan kalıtımdır.
programlama ve onu destekleyen diller.
Nesne yönelimli programlamanın diğer bir özelliği,
yöntem çağrılarının yöntemlere dinamik olarak bağlanması da kapsamlı bir şekilde tartışılmaktadır.
bu bölüm.
Nesne yönelimli programlama bazı işlevler tarafından desteklense de
CLOS, OCaml ve F# gibi ulusal diller, bu diller
bu bölümde tartışılmıştır.

Sayfa 546
12.2 Nesneye Yönelik Programlama 525
12.2 Nesne Yönelimli Programlama
12.2.1 Giriş
Nesne yönelimli programlama kavramının kökleri SIMULA 67'deydi, ancak
Smalltalk'ın evrimi Smalltalk 80 ile sonuçlanana kadar tam olarak geliştirilmemiştir.
(tabii ki 1980'de). Gerçekten de, bazıları Smalltalk'ın temel model olduğunu düşünüyor.
tamamen nesne yönelimli bir programlama dili. Nesne kökenli bir dil
ented üç temel dil özelliği için destek sağlamalıdır: soyut veri türleri,
kalıtım ve yöntem çağrılarının yöntemlere dinamik bağlanması. Soyut veri türleri
Bölüm 11'de ayrıntılı olarak tartışılmıştır, dolayısıyla bu bölüm miras ve
dinamik bağlama.
12.2.2 Miras
Yazılım geliştiriciler üzerinde, üretimlerini artırmaları için uzun süredir baskı var.
hareketlilik. Bu baskı, maliyette devam eden düşüşle yoğunlaştı.
bilgisayar donanımı. 1980'lerin ortalarından sonlarına kadar, birçok kişi için belirgin hale geldi.
artırmak için en umut verici fırsatlardan biri olan yazılım geliştiricileri
mesleklerindeki üretkenlik, yazılımın yeniden kullanımındaydı. Soyut veri türleri,
kapsülleme ve erişim kontrolleri, açıkça yeniden kullanım için adaylardır.
Soyut veri türlerinin yeniden kullanımıyla ilgili sorun, hemen hemen her durumda,
mevcut türün özellikleri ve yetenekleri yeni için pek doğru değil
kullanmak. Eski tip, en azından bazı küçük değişiklikler gerektirir. Bu tür değişiklikler
değişiklikler zor olabilir, çünkü değişikliği yapan kişiye ihtiyaç duyarlar.
mevcut kodun tamamını olmasa da bir kısmını anlamak için. Birçok durumda, kişi
değişikliği yapmak programın orijinal yazarı değil. Ayrıca, içinde
çoğu durumda, değişiklikler tüm istemci programlarında değişiklik yapılmasını gerektirir.
Soyut veri türleri ile programlama ile ilgili ikinci bir problem,
tip tanımlarının tamamı bağımsızdır ve aynı seviyededir. Bu tasarım genellikle
problem alanıyla eşleşecek bir program organize etmeyi imkansız hale getirir.
program tarafından ele alınmıştır. Çoğu durumda, altta yatan sorunun kategorileri vardır:
hem kardeş olarak (birbirine benzer) hem de birbiriyle ilişkili nesne dizileri.
ebeveynler ve çocuklar olarak (soy ilişkisine sahip olmak).
Kalıtım, ortaya çıkan değişiklik sorununa bir çözüm sunar.
soyut veri türü yeniden kullanımı ve program organizasyon sorunu ile. eğer yeni
soyut veri türü, mevcut bazı türlerin verilerini ve işlevlerini devralabilir,
ve ayrıca bu varlıkların bazılarını değiştirmesine ve yeni varlıklar eklemesine, yeniden kullanmasına izin verilir.
yeniden kullanılan soyut veri tipinde değişiklik gerektirmeden büyük ölçüde kolaylaştırılmıştır.
Programcılar mevcut bir soyut veri tipiyle başlayabilir ve bir mod tasarlayabilir.
yeni bir sorun gereksinimine uyması için onun soyundan geldi. Ayrıca, miras-
tance, ilgili sınıfların hiyerarşilerinin tanımı için bir çerçeve sağlar.
Bu, problem uzayındaki astsal ilişkileri yansıtabilir.
Nesne yönelimli dillerdeki soyut veri türleri,
SIMULA 67, genellikle sınıflar olarak adlandırılır . Soyut veri türlerinin örneklerinde olduğu gibi,
sınıf örneklerine nesneler denir . Kalıtım yoluyla tanımlanan bir sınıf

Sayfa 547
526
Bölüm 12 Nesne Yönelimli Programlama Desteği
başka bir sınıftan türetilmiş bir sınıf veya alt sınıftır . Yeni gelen bir sınıf
sınıf türetilmiştir, üst sınıfı veya üst sınıfıdır . tanımlayan alt programlar
bir sınıfın nesneleri üzerindeki işlemlere yöntemler denir . Yöntemlere yapılan çağrılar
bazen mesajlar denir . Bir nesnenin tüm yöntem koleksiyonu
nesnenin mesaj protokolü veya mesaj arayüzü olarak adlandırılır . bilgisayar
Nesne yönelimli bir programdaki görevler, nesnelerden gönderilen mesajlarla belirlenir.
diğer nesnelere veya bazı durumlarda sınıflara.
Bir mesajı iletmek gerçekten bir alt programı çağırmaktan farklıdır. bir alt pro-
gram tipik olarak arayanı tarafından parametre olarak geçirilen verileri işler.
veya yerel olmayan veya genel olarak erişilir. Bir nesneye gönderilen bir mesaj bir istektir
yöntemlerinden birini yürütmek için. Yöntemin üzerinde durduğu verilerin en azından bir kısmı
çalışmaktır, nesnenin kendisidir. Nesneler, süreçleri tanımlayan yöntemlere sahiptir.
nesne kendi üzerinde çalışabilir. Nesneler soyut veri türlerinden olduğu için,
bunlar nesneyi manipüle etmenin tek yolu olmalıdır. Bir alt program tanımlar
kendisine gönderilen (veya bağımsız olarak kullanıma sunulan) herhangi bir veri üzerinde gerçekleştirebileceği bir işlemdir.
çağrılır veya global).
Basit bir kalıtım örneği olarak şunları göz önünde bulundurun:
Yıl, renk ve marka için değişkenleri olan Vehicles adlı bir sınıfa sahip olun. A
bunun doğal uzmanlığı veya alt sınıfı, miras alabilecek Truck olacaktır.
Araç değişkenleri , ancak taşıma kapasitesi için değişkenler ekler ve
tekerlek sayısı. Şekil 12.1, ilişkiyi gösteren basit bir diyagramı göstermektedir.
Araç sınıfı ile Kamyon sınıfı arasındaki ilişki , ok işaretinin gösterildiği
ebeveyn sınıfına işaret eder.
Türetilmiş bir sınıfın ebeveyninden farklı olmasının birkaç yolu vardır. 1 Takip ediliyor
bir üst sınıf ile alt sınıfları arasındaki en yaygın farklar şunlardır:
1. Üst sınıf, sahip olması için bazı değişkenlerini veya yöntemlerini tanımlayabilir.
özel erişim, yani alt sınıfta görünmeyecekler.
2. Alt sınıf, kendisinden devralınanlara değişkenler ve/veya yöntemler ekleyebilir.
ebeveyn sınıfı.
3. Alt sınıf, miras alınan bir veya daha fazlasının davranışını değiştirebilir.
yöntemler. Değiştirilmiş bir yöntem aynı ada ve genellikle aynı ada sahiptir.
protokol, bir değişiklik olduğu gibi.
Yeni yöntemin, devralınan yöntemi geçersiz kıldığı söylenir , bu daha sonra
geçersiz kılınan bir yöntem denir . Geçersiz kılma yönteminin amacı,
1. Bir alt sınıf, ebeveyninden farklı değilse, açıkça hiçbir amaca hizmet etmez.
Şekil 12.1
Basit bir örnek
miras
Araç
kamyon

Sayfa 548
12.2 Nesne Yönelimli Programlama 527
alt sınıfta, ana sınıftakine benzer bir işlem sağlar,
ancak alt sınıfın nesneleri için özelleştirilmiştir. Örneğin, bir üst sınıf olan Bird ,
jenerik bir kuş çizen bir çizim yöntemine sahip olabilir . adlı Bird alt sınıfı
Su kuşları geçersiz olabilir beraberlik miras yöntemini Bird bir çizmek
genel su kuşları, belki bir ördek.
Sınıfların iki tür yöntemi ve iki tür değişkeni olabilir. en
yaygın olarak kullanılan yöntemler ve değişkenler, örnek yöntemler ve örnek olarak adlandırılır.
değişkenler . Bir sınıfın her nesnesinin, depolayan kendi örnek değişkenleri kümesi vardır.
nesnenin durumu. Aynı sınıftan iki nesne arasındaki tek fark,
örnek değişkenlerinin durumu. 2 Örneğin, arabalar için bir sınıf
renk, marka, model ve yıl için örnek değişkenler. Örnek yöntemleri çalışır
sadece sınıfın nesneleri üzerinde. Sınıf değişkenleri , sınıfa değil, sınıfa aittir.
nesnesi olduğundan, sınıf için yalnızca bir kopya vardır. Örneğin, istersek
bir sınıfın örneklerini sayın, sayaç bir örnek olamaz
değişken—bir sınıf değişkeni olması gerekir. Sınıf yöntemleri , işlemleri gerçekleştirebilir.
sınıfa ve muhtemelen sınıfın nesnelerine de bağlıdır.
Yeni bir sınıf, tek bir ebeveyn sınıfın alt sınıfıysa, türetme pro-
cess tek kalıtım olarak adlandırılır . Bir sınıfın birden fazla üst sınıfı varsa,
sürece çoklu kalıtım denir . Birkaç sınıf ilişkili olduğunda
tek kalıtım yoluyla, birbirleriyle ilişkileri bir şekilde gösterilebilir.
türetme ağacı. Çoklu kalıtımdaki sınıf ilişkileri gösterilebilir
bir türetme grafiğinde.
Kalıtımın bir dezavantajı, olasılığını artırmanın bir yolu olarak
yeniden kullanım, bir kalıtım hiyerarşisindeki sınıflar arasında bağımlılıklar yaratmasıdır.
arki. Bu sonuç, soyut veri türlerinin avantajlarından birine karşı çalışır,
yani birbirlerinden bağımsız olmalarıdır. Tabii ki, hepsi soyut değil
veri türleri tamamen bağımsız olmalıdır. Ama genel olarak bağımsızlık
soyut veri türlerinin en güçlü olumlu özelliklerinden biridir. Ancak,
soyut verilerin yeniden kullanılabilirliğini artırmak imkansız olmasa da zor olabilir
bazıları arasında bağımlılık yaratmadan türler. Ayrıca, içinde
birçok durumda, bağımlılıklar doğal olarak temeldeki bağımlılıkları yansıtır
sorun alanı.
12.2.3 Dinamik Bağlama
Nesnenin üçüncü özelliği (soyut veri türleri ve kalıtımdan sonra)
programlama dilleri yönlendirilmiş polimorfizm bir tür 3 sağladığı
mesajların yöntem tanımlarına dinamik olarak bağlanması. Bu bazen denir
dinamik gönderme . Aşağıdaki durumu göz önünde bulundurun: Bir temel sınıf var, A ,
tabanla ilişkili bir şekil çizen bir yöntem çizimini tanımlayan
sınıf. İkinci bir sınıf olan B , A'nın bir alt sınıfı olarak tanımlanır . Bu yeni sınıfın nesneleri
ayrıca A tarafından sağlanana benzer ancak biraz farklı bir çizim yöntemine ihtiyacınız var
2. Aynı sınıftaki farklı nesnelerin diğer sınıflarda farklı olmasına izin veren Ruby'de bu doğru değildir.
yollar.
3. Polimorfizm Bölüm 9'da tanımlanmıştır.

Sayfa 549
528
Bölüm 12 Nesne Yönelimli Programlama Desteği
çünkü alt sınıf nesneleri biraz farklıdır. Yani, alt sınıf geçersiz kılar
devralınan çekme yöntemi. A ve B'nin bir müşterisinin referans olan bir değişkeni varsa,
A sınıfının nesnelerine ilişkin olarak, bu referans aynı zamanda B sınıfının nesnelerine de işaret edebilir ,
bunu polimorfik bir referans haline getiriyor . Eğer metotta tanımlanan draw ,
her iki sınıf, çalışma zamanı sistemi olan polimorfik referans aracılığıyla çağrılır.
yürütme sırasında hangi yöntemin çağrılacağını belirlemeli, A 's veya B 's
(hangi tür nesneye şu anda başvuruda bulunulduğunu belirleyerek). 4
Şekil 12.2 bu durumu göstermektedir.
Polimorfizm, nesne yönelimli herhangi bir dilin doğal bir parçasıdır.
statik olarak yazılmıştır. Bir anlamda polimorfizm, statik olarak yazılan bir dili
biraz dinamik olarak yazılmış, burada küçük biraz yöntemin bazı bağlamalarında
yöntemlere çağrı yapar. Bir polimorfik değişkenin türü gerçekten dinamiktir.
Az önce açıklanan yaklaşım, polimorfik tasarlamanın tek yolu değildir.
Referanslar. Objective-C'de kullanılan bir alternatif,
Bölüm 12.6.3.
Dinamik bağlamanın bir amacı, yazılım sistemlerinin daha
hem geliştirme hem de bakım sırasında kolayca genişletilebilir. Diyelim ki
bir araba sınıfı ve her biri için bir alt sınıf olarak uygulanan kullanılmış arabaların bir kataloğu
Katalogdaki araba. Alt sınıflar, arabanın bir görüntüsünü ve özel bilgileri içerir.
araba hakkında Kullanıcılar, görüntüleyen bir programla arabalara göz atabilir.
kullanıcı ona göz atarken her bir araba hakkındaki resimler ve bilgiler. ekran
her arabanın (ve bilgilerinin), kullanıcının tıklayabileceği bir düğme içerir.
o belirli araba ile ilgileniyor. Tüm kataloğu inceledikten sonra veya
Katalog, kullanıcının görmek istediği kadar, sistem resimleri basacaktır.
ve kullanıcıyı ilgilendiren arabalar hakkında bilgi. Uygulamanın bir yolu
bu sistem, bir dizideki ilgilenilen her arabanın nesnesine bir referans yerleştirmektir.
temel sınıfa yapılan referanslar, car . Kullanıcı hazır olduğunda, hakkında bilgi
İlgilenilen tüm arabalar, kullanıcının incelemesi ve karşılaştırması için basılabilir
Listedeki arabalar. Arabaların listesi elbette sık sık değişecektir. Bu irade
arabanın alt sınıflarında karşılık gelen değişiklikleri gerektirir . Ancak, değişiklikler
alt sınıfların toplanması, sistemde başka herhangi bir değişiklik gerektirmez.
4. Yöntem çağrılarının yöntemlere dinamik olarak bağlanmasına bazen dinamik polimorfizm denir .
Şekil 12.2
dinamik bağlama
genel sınıf A {
. . .
Berabere( ) {. . .}
. . .
}
public class B , A'yı genişletir {
. . .
Berabere( ) {. . .}
. . .
}
müşteri
. . .
A myA = yeni A ( );
myA.draw ( );
. . .

Sayfa 550
Bazı durumlarda, bir kalıtım hiyerarşisinin tasarımı bir veya
hiyerarşide o kadar yüksek olan daha fazla sınıf ki, bunların bir örneği
mantıklı olmazdı. Örneğin, bir programın bir Bina tanımladığını varsayalım.
belirli bina türleri için sınıf ve alt sınıflar koleksiyonu, örneğin,
Fransız_Gotik . Uygulanması muhtemelen mantıklı olmaz
Binada çizim yöntemi . Ancak onun soyundan gelen tüm sınıfların
böyle bir uygulanmış yönteme sahip olmak, bunun protokolü (ancak gövdesi değil)
yöntemi Building'e dahildir . Böyle bir yönteme genellikle soyut denir.
yöntem ( C++'da saf sanal yöntem ). En az bir özet içeren bir sınıf
yönteme soyut sınıf ( C++'da soyut temel sınıf ) denir . Böyle bir sınıf genellikle
somutlaştırılamaz, çünkü bazı yöntemleri bildirilmiş ancak bildirilmemiştir.
tanımlanmış (gövdeleri yoktur). olacak bir soyut sınıfın herhangi bir alt sınıfı
somutlaştırılan, devralınan tüm öğelerin uygulamalarını (tanımlarını) sağlamalıdır.
soyut yöntemler.
12.3 Nesne Yönelimli Diller için Tasarım Sorunları
Programlama planı tasarlanırken bir dizi konu dikkate alınmalıdır.
kalıtımı ve dinamik bağlamayı destekleyen guage özellikleri. Biz olanlar
en önemlileri bu bölümde tartışılmaktadır.
12.3.1 Nesnelerin Münhasırlığı
Kendini tamamen bilgisayar nesne modeline adamış bir dil tasarımcısı.
tion, diğer tüm tür kavramlarını kapsayan bir nesne sistemi tasarlar. Her-
Basit bir skaler tam sayıdan eksiksiz bir yazılım sistemine kadar her şey, bir nesnedir.
bu zihniyet. Bu seçimin avantajı zarafet ve saf tekdüzeliktir.
dil ve kullanımı. Birincil dezavantaj, basit işlemlerin
mesaj iletme süreci aracılığıyla yapılmalıdır, bu da genellikle onları
tek makinenin olduğu zorunlu bir modelde benzer işlemlerden daha yavaş
talimatlar bu tür basit işlemleri uygular. Bu en saf nesne modelinde
odaklı hesaplama, tüm türler sınıflardır. arasında ayrım yoktur
önceden tanımlanmış ve kullanıcı tanımlı sınıflar. Aslında, tüm sınıflara aynı şekilde davranılır
ve tüm hesaplama mesaj geçişi yoluyla gerçekleştirilir.
Emperyalizmde yaygın olan nesnelerin özel kullanımına bir alternatif.
nesne yönelimli programlamanın desteklendiği diller
eklenen geleneksel bir zorunluluktan türlerin tam koleksiyonunu korumaktır
programlama dili ve nesne yazma modelini eklemeniz yeterlidir. Bu yaklaşım
tür yapısı herkes için kafa karıştırıcı olabilen daha büyük bir dille sonuçlanır, ancak
uzman kullanıcılar.
Nesnelerin münhasır kullanımına bir başka alternatif, bir buyruk sahibi olmaktır.
ilkel skaler türler için stil türü yapısı, ancak yapılandırılmış tüm öğeleri uygulayın
nesneler olarak türler. Bu seçim, ilkel sistemlerde işlemlerin hızını sağlar.
zorunlu modelde beklenenlerle karşılaştırılabilir değerler. talihsiz-
Doğal olarak bu alternatif dilde de karışıklıklara yol açmaktadır. her zaman
12.3 Nesne Yönelimli Diller için Tasarım Sorunları 529

Sayfa 551
530
Bölüm 12 Nesne Yönelimli Programlama Desteği
nesne olmayan değerler nesnelerle karıştırılmalıdır. Bu sözde bir ihtiyaç yaratır
nesne olmayan türler için sarmalayıcı sınıfları , böylece yaygın olarak ihtiyaç duyulan bazı işlemler
sarmalayıcı sınıfın yöntemleri olarak uygulanabilir. Ne zaman böyle bir
nesne olmayan bir değer için işlem gereklidir, değer bir nesneye dönüştürülür
ilişkili sarmalayıcı sınıfının ve sarmalayıcı sınıfının uygun yönteminin
kullanıldı. Bu tasarım, verimlilik için bir dil bütünlüğü ve saflığı ticaretidir.
12.3.2 Alt Sınıflar Alt Türler midir?
Buradaki mesele nispeten basittir: arasında bir “bir-dir” ilişkisi var mıdır?
türetilmiş bir sınıf ve onun ana sınıfı? Tamamen semantik bir bakış açısından, eğer bir
türetilmiş sınıf bir üst sınıfsa, türetilmiş sınıfın nesneleri tüm
üst sınıfın nesneleri tarafından açığa çıkarılan üyelerin sayısı. Daha az soyut
düzeyde, bir is-a ilişkisi, müşteride türetilmiş bir değişkenin
sınıf türü, ana sınıf türünün bir değişkeninin yasal olduğu her yerde görünebilir,
bir tür hatasına neden olmadan. Ayrıca, türetilmiş sınıf nesneleri
üst sınıf nesnelerine davranışsal olarak eşdeğerdir.
Ada'nın alt türleri, bu basit kalıtım biçiminin örnekleridir.
veri. Örneğin,
alt türü Small_Int , Tamsayı aralığı -100..100;
Değişkenler Small_Int tür işlemlerin tümüne sahip tamsayı değişkenleri
ancak Integer içinde mümkün olan değerlerin yalnızca bir alt kümesini saklayabilir . Üstelik,
her Small_Int değişkeni, bir Tamsayı değişkeninin olabileceği her yerde kullanılabilir
Kullanılmış. Yani, her Small_Int değişkeni bir anlamda bir Tamsayı değişkenidir.
Bir alt sınıfın kendisinden farklı olabileceği çok çeşitli yollar vardır.
temel veya ana sınıf. Örneğin, alt sınıfın ek yöntemleri olabilir,
daha az yönteme sahip olabilir, bazı parametrelerin türleri farklı olabilir
bir veya daha fazla metotta, bazı metotların dönüş tipi farklı olabilir,
Bazı yöntemlerin parametre sayısı farklı olabilir veya bir veya birden fazla yöntemin gövdesi farklı olabilir.
daha fazla yöntem farklı olabilir. Çoğu programlama dili ciddi şekilde
bir alt sınıfın temel sınıftan farklı olma biçimlerini kısıtlar. Çoğu durumda,
dil kuralları, alt sınıfı, üst sınıfının bir alt türü olarak kısıtlar.
Daha önce belirtildiği gibi, türetilmiş bir sınıf, eğer bir is-a ilişkisine sahipse, alt tip olarak adlandırılır.
ebeveyn sınıfı ile iletişim. Bunu sağlayan bir alt sınıfın özellikleri
bir alt türdür: Üst sınıfı geçersiz kılan alt sınıfın yöntemleri
yöntemler, karşılık gelen geçersiz kılınan yöntemlerle tür uyumlu olmalıdır.
Burada uyumlu olması, geçersiz kılma yöntemine yapılan bir çağrının herhangi bir çağrının yerini alabileceği anlamına gelir.
neden olmaksızın istemci programında herhangi bir görünümde geçersiz kılınan yönteme
tip hataları. Bu, her geçersiz kılma yönteminin aynı olması gerektiği anlamına gelir.
geçersiz kılınan yöntem olarak parametre sayısı ve parametre türleri
ve dönüş türü, ana sınıfınkilerle uyumlu olmalıdır. sahip olmak
özdeş sayıda parametre ve özdeş parametre türleri ve dönüş türü
elbette, bir yöntemin uygunluğunu garanti eder. Daha az ciddi kısıtlamalar
ancak dilin tür uyumluluk kurallarına bağlı olarak mümkündür.

Sayfa 552
12.3 Nesne Yönelimli Diller için Tasarım Sorunları 531
Alt tür tanımımız, kamu kuruluşlarına açıkça izin vermemektedir.
alt sınıfta da genel olmayan üst sınıf. Yani, türetme işlemi
alt türler için, üst sınıfın genel varlıklarının miras alınmasını gerektirmelidir
alt sınıftaki kamu varlıkları olarak.
Alt tip ilişkilerinin ve kalıtım ilişkilerinin
neredeyse özdeş. Ancak bu varsayım doğru olmaktan uzaktır. bir açıklama
bu yanlış varsayım, bir C++ örneği ile birlikte Bölüm 12.5.2'de verilmiştir.
12.3.3 Tek ve Çoklu Kalıtım
Diğer bir basit konu ise şudur: Dil, çoklu kalıtımı mümkün kılıyor mu?
tek kalıtım)? Belki o kadar basit değildir. Çoklu kullanım amacı
kalıtım, yeni bir sınıfın iki veya daha fazla sınıftan miras almasına izin vermektir.
Çoklu kalıtım bazen son derece yararlı olduğundan, neden bir
dil tasarımcısı dahil değil mi? Sebepler iki kategoride yatmaktadır: karmaşıklık
ve verimlilik. Ek karmaşıklık birkaç problemle gösterilmektedir.
İlk olarak, bir sınıfın birbiriyle ilgisiz iki üst sınıfı varsa ve bunların hiçbiri tanımlamazsa şunu unutmayın:
diğerinde tanımlanmış bir isim, sorun yok. Ancak, varsayalım ki bir
adı alt sınıfı iki sınıftan devralır bir sınıf B ve her ikisi de bir ve oda tanımlayan
display adlı kalıtsal bir yöntem . Eğer C her iki sürümü başvurmak gerekiyor
bir ekran , bu nasıl yapılabilir? Bu belirsizlik sorunu daha da karmaşıktır.
iki ana sınıfın her ikisi de aynı adlandırılmış yöntemleri tanımladığında çoğaltılır
ve bunlardan biri veya her ikisi alt sınıfta geçersiz kılınmalıdır.
Her ikisi de eğer başka bir sorun ortaya çıkar bir ve B , ortak bir ana elde edilir,
Z , vehem de sahiptir A ve B üst sınıfları. Bu duruma elmas denir
veya ortak miras. Bu durumda, her iki A ve B içermelidir Z ‘nin kalıtsal
değişkenler. Z'nin sum adında kalıtsal bir değişken içerdiğini varsayalım . Soru
olup olmadığıdır C hem sürümlerini alması gerektiğini toplamı , sadece bir veya eğer sadece bir tane ve
hangisi? Sadece birinin olduğu programlama durumları olabilir.
ikisi kalıtsal, diğer ikisi de kalıtsal olmalıdır. Bölüm
12.11, bu durumların uygulanmasına kısa bir bakış içerir. Elmas
kalıtım Şekil 12.3'te gösterilmektedir.
Verimlilik sorunu gerçek olmaktan çok algılanabilir. C++ için,
örneğin, çoklu kalıtımı desteklemek, yalnızca bir ek dizi gerektirir
dinamik olarak bağlı her yöntem için erişim ve bir ekstra ekleme işlemi
çağrı, en azından bazı makine mimarilerinde (Stroustrup, 1994, s. 270).
Program birden fazla kullanmasa bile bu işlem gerekli olsa da
miras, küçük bir ek maliyettir.
Şekil 12.3
Bir elmas örneği
miras
Z
C
A
B

Sayfa 553
532
Bölüm 12 Nesne Yönelimli Programlama Desteği
Çoklu kalıtımın kullanımı kolayca karmaşık program organizasyonuna yol açabilir.
zonlar. Çoklu kalıtımı kullanmayı deneyen birçok kişi şunu buldu:
sınıfları çoklu ebeveyn olarak kullanılabilecek şekilde tasarlamak zordur. Bakım onarım
çoklu kalıtım kullanan sistemlerin sayısı daha ciddi bir sorun olabilir, çünkü
çoklu kalıtım, sınıflar arasında daha karmaşık bağımlılıklara yol açar. Bu
bazılarına göre çoklu kalıtımın faydalarının katma değer olduğu net değil
onu kullanan bir sistem tasarlama ve sürdürme çabası.
Arayüzler, çoklu kalıtımın bir alternatifidir. Arayüzler sağlar
çoklu kalıtımın yararlarından bazıları, ancak daha az dezavantajı vardır.
12.3.4 Nesnelerin Tahsisi ve Yerinden Çıkarılması
Tahsis ve serbest bırakma ile ilgili iki tasarım sorusu vardır.
nesnelerin. Bunlardan ilki, nesnelerin tahsis edildiği yerdir. Eğer
soyut veri türleri gibi davranırlar, o zaman belki tahsis edilebilirler
herhangi bir yerden. Bu, çalışma zamanı yığınından ayrılabilecekleri anlamına gelir.
veya new gibi bir operatör veya işlevle öbek üzerinde açıkça oluşturulur . Eğer
hepsi yığın dinamiğidir, tek tip bir yönteme sahip olmanın avantajı vardır.
işaretçi veya referans değişkenleri aracılığıyla oluşturma ve erişim. Bu tasarım basit-
nesneler için atama işlemini başlatır, her durumda yalnızca bir işaretçi yapar
veya referans değeri değişikliği. Ayrıca nesnelere yapılan referansların örtük olarak olmasına izin verir.
referanssız, erişim sözdizimini basitleştirir.
Nesneler yığın dinamik ise, alt türlerle ilgili bir sorun vardır. Eğer
Sınıf B sınıfı bir çocuk A ve B bir alt tipi olan , A , daha sonra bir amacı B tipi kutu
A tipi bir değişkene atanabilir . Örneğin, b1 , B tipi bir değişkense ve
a1 , A tipi bir değişkendir , o zaman
a1 = b1;
yasal bir açıklamadır. Eğer a1 ve b1 yığın dinamik nesneler için referanslar, orada
sorun değil—atama basit bir işaretçi atamasıdır. Ancak, eğer
a1 ve b1 yığın dinamiktir, bu durumda değer değişkenleridir ve atanmışsa
nesnenin değeri, hedef nesnenin alanına kopyalanmalıdır. Eğer B ekler
A'dan miras aldığına bir veri alanı , o zaman a1 yeterli alana sahip olmayacak
tüm b1 için yığında . Fazlalık basitçe kesilecektir, ki bu
kodu yazan veya kullanan programcılar için kafa karıştırıcı. Bu kesme denir
nesne dilimleme . Aşağıdaki örnek ve Şekil 12.4 sorunu göstermektedir.
A sınıfı {
int x;
. . .
};
B sınıfı : A {
int y;
. . .
}

Sayfa 554
12.3 Nesne Yönelimli Diller için Tasarım Sorunları 533
Buradaki ikinci soru, nesnelerin
yığından ayrılır. Soru, serbest bırakmanın örtük olup olmadığıdır,
açık veya her ikisi. Serbest bırakma örtülü ise, bazı örtülü depolama yöntemi
ıslah gereklidir. Serbest bırakma açık olabilirse, bu şu sorunu gündeme getirir:
sarkan işaretçiler veya referanslar oluşturulabilir.
12.3.5 Dinamik ve Statik Bağlama
Tartıştığımız gibi, mesajların yöntemlere dinamik olarak bağlanması çok önemlidir.
nesne yönelimli programlamanın bir parçasıdır. Buradaki soru, her şeyin bağlayıcı olup olmadığıdır.
Mesajların metotlara aktarılması dinamiktir. Alternatif, kullanıcının
belirli bir bağlamanın dinamik mi yoksa statik mi olacağını belirtin. Avantaj
Bunun nedeni, statik bağlamaların daha hızlı olmasıdır. Dolayısıyla, bir bağlamanın dinamik olması gerekmiyorsa,
neden bedelini ödesin?
12.3.6 İç İçe Sınıflar
Sınıf tanımlarını iç içe yerleştirmek için birincil motivasyonlardan biri bilgi gizlemedir.
ing. Yalnızca bir sınıf için yeni bir sınıfa ihtiyaç duyuluyorsa, onu tanımlamanın bir nedeni yoktur.
diğer sınıflar tarafından görülebilir. Bu durumda, yeni sınıf iç içe yerleştirilebilir.
onu kullanan sınıf. Bazı durumlarda, yeni sınıf bir alt programın içine yerleştirilmiştir.
doğrudan başka bir sınıfta değil.
Yeni sınıfın yuvalandığı sınıfa yuvalama sınıfı denir . bu
sınıf iç içe yerleştirmeyle ilgili en belirgin tasarım sorunları görünürlükle ilgilidir.
Spesifik olarak, bir sorun şudur: Yuvalama sınıfının hangi olanakları görünür?
yuvalanmış sınıfta? Diğer ana konu ise tam tersi: Tesislerden hangisi
iç içe sınıfın iç içe geçmiş sınıfında görünür mü?
12.3.7 Nesnelerin Başlatılması
Başlatma sorunu, nesnelerin değerlere başlatılıp başlatılmayacağı ve nasıl başlatılacağıdır.
yaratıldıkları zaman. Bu, ilk düşünülenden daha karmaşıktır.
İlk soru, nesnelerin manuel olarak mı yoksa aracılığıyla mı başlatılması gerektiğidir.
bazı örtük mekanizma. Bir alt sınıfın nesnesi oluşturulduğunda,
Şekil 12.4
Bir nesne örneği
dilimleme
veri alanı
veri alanı
yığın
x
y
x
b1
a1

Sayfa 555
534
Bölüm 12 Nesne Yönelimli Programlama Desteği
kalıtsal üst sınıf üyesinin ilişkili başlatması örtük veya zorunlu
programcı açıkça onunla ilgilenir.
12.4 Smalltalk'ta Nesne Yönelimli Programlama Desteği
Çoğu kişi Smalltalk'ı kesin nesne yönelimli programlama dili olarak düşünür.
ölçü. Bu paradigma için tam destek içeren ilk dildi.
Bu nedenle, nesne yönelimli dil desteği için bir araştırma başlatmak doğaldır.
Smalltalk ile programlama.
12.4.1 Genel Özellikler
Smalltalk'ta bir nesne kavramı gerçekten evrenseldir. neredeyse her şey,
tamsayı sabiti 2 kadar basit öğelerden karmaşık bir dosya işleme sistemine
tem, bir nesnedir. Nesneler olarak, aynı şekilde muamele görürler. hepsinin yerlisi var
bellek, doğal işleme yeteneği, diğerleriyle iletişim kurma yeteneği
nesneler ve yöntemlerden ve örnek değişkenlerden miras alma olasılığı
atalar. Smalltalk'ta sınıflar iç içe olamaz.
Tüm hesaplama mesajlar aracılığıyla, hatta basit bir aritmetik işlemle yapılır.
Örneğin, x + 7 ifadesi , + mesajını göndererek uygulanır .
x ( + yöntemini yürürlüğe koymak için ), parametre olarak 7 gönderiyor . Bu işlem döner
eklemenin sonucuyla birlikte yeni bir sayısal nesne.
Mesajlara verilen yanıtlar nesne biçimindedir ve geri dönmek için kullanılır.
talep edilen veya hesaplanan bilgiler veya yalnızca talep edilen bilgilerin
hizmet tamamlandı.
Tüm Smalltalk nesneleri öbekten ayrılır ve bunlara başvurulur
dolaylı olarak başvurulan başvuru değişkenleri aracılığıyla. yok
açık ayırma ifadesi veya işlemi. Tüm serbest bırakma, örtük olarak kullanılır.
depolama ıslahı için bir çöp toplama işlemi.
Smalltalk'ta, bir nesne oluşturulduğunda yapıcılar açıkça çağrılmalıdır.
Bir sınıfın birden çok yapıcısı olabilir, ancak her birinin benzersiz bir adı olmalıdır.
C++ ve Ada 95 gibi hibrit dillerin aksine Smalltalk,
yalnızca bir yazılım geliştirme paradigması için—nesne yönelimli. Üstelik,
zorunlu dillerin hiçbir görünümünü benimsemez. Onun saflığı-
poz, sade zarafetine ve tasarım tekdüzeliğine yansır.
Bölüm 2'de örnek bir Smalltalk programı vardır.
12.4.2 Kalıtım
Bir Smalltalk alt sınıfı, tüm örnek değişkenlerini, örnek yöntemlerini,
ve üst sınıfının sınıf yöntemleri. Alt sınıfın kendi örneği de olabilir
değişken adlarından farklı adlara sahip olması gereken değişkenler
onun ata sınıfları. Son olarak, alt sınıf yeni yöntemler tanımlayabilir ve yeniden tanımlayabilir.
bir ata sınıfında zaten var olan yöntemler. Bir alt sınıfın bir yöntemi olduğunda
adı ve protokolü bir ata sınıfla aynı olan alt sınıf yöntemi

Sayfa 556
Smalltalk Nesne Tabanlı Programlama İçin 12.4 Desteği 535
ata sınıfınınkini gizler. Böyle bir gizli yönteme erişim, aşağıdakiler tarafından sağlanır:
mesajın önüne süper sözde değişkeni eklemek . Önek neden olur
yerel olarak değil üst sınıfta başlamak için yöntem araması.
Bir üst sınıftaki varlıklar alt sınıflardan gizlenemeyeceğinden, tümü
alt sınıflar alt türlerdir.
Smalltalk, tekli devralmayı destekler; çoklu mirasa izin vermez.
12.4.3 Dinamik Bağlama
İletilerin Smalltalk'taki yöntemlere dinamik olarak bağlanması şu şekilde çalışır:
Bir nesneye gönderilen mesaj, nesnenin ait olduğu sınıfın aranmasına neden olur.
karşılık gelen bir yöntem için. Arama başarısız olursa, süper-
bu sınıfın sınıfı ve benzeri, sistem sınıfına kadar, Object hiçbir değeri yoktur.
süper sınıf. Nesne , her sınıfın üzerinde bulunduğu sınıf türetme ağacının köküdür.
bir düğümdür. Bu zincirin herhangi bir yerinde herhangi bir yöntem bulunamazsa, bir hata oluşur. o
Bu yöntem aramasının dinamik olduğunu hatırlamak önemlidir;
mesaj gönderildiğinde. Smalltalk hiçbir koşulda bağlayıcı değildir.
statik olarak yöntemlere mesajlar.
Smalltalk'taki tek tip denetimi dinamiktir ve tek tip hatası
Eşleştirme yöntemi olmayan bir nesneye bir mesaj gönderildiğinde oluşur.
yerel olarak veya miras yoluyla. Bu, tip denetiminin farklı bir kavramıdır.
diğer dillerin çoğu. Smalltalk tip denetiminin basit bir amacı vardır:
bir mesajın bazı yöntemlerle eşleşmesini sağlamak.
Smalltalk değişkenleri yazılmaz; herhangi bir isim herhangi bir nesneye bağlanabilir. Olarak
doğrudan bir sonuç, Smalltalk dinamik polimorfizmi destekler. Tüm Smalltalk kodu
Değişkenlerin türlerinin alakasız olduğu sürece geneldir.
tutarlıdır. Değişken üzerindeki bir işlemin (yöntem veya operatör) anlamı
değişkenin bağlı olduğu nesnenin sınıfı tarafından belirlenir.
Bu tartışmanın amacı, bir metinde atıfta bulunulan nesneler olduğu sürece,
ifade, ifadenin mesajları için yöntemlere sahiptir, ifade türleri
nesneler önemsizdir. Bu, hiçbir kodun belirli bir türe bağlı olmadığı anlamına gelir.
12.4.4 Küçük Konuşmanın Değerlendirilmesi
Smalltalk sistemi büyük olmasına rağmen, Smalltalk küçük bir dildir. Sen-
dilin vergisi basit ve son derece düzenlidir. için iyi bir örnektir.
küçük bir dil tarafından sağlanabilecek güç, eğer o dil etrafında inşa edilmişse
basit ama güçlü bir kavram. Smalltalk söz konusu olduğunda, bu kavram, tüm
programlama, yalnızca miras kullanılarak oluşturulan bir sınıf hiyerarşisi kullanılarak yapılabilir.
tance, nesneler ve mesaj geçişi.
Geleneksel derlenmiş zorunlu dil programlarıyla karşılaştırıldığında,
eşdeğer Smalltalk programları önemli ölçüde daha yavaştır. Teo-
içinde dizi indeksleme ve döngülerin sağlanabilmesi oldukça ilginçtir.
mesaj iletme modelinde verimlilik, değerlendirmede önemli bir faktördür.
Programlama dilleri. Bu nedenle, verimlilik çoğu durumda açıkça bir sorun olacaktır.
Smalltalk'ın pratik uygulanabilirliği üzerine tartışmalar.

Sayfa 557
röportaj yapmak
Paradigmalar ve Daha İyi Programlama Üzerine
BJARNE STROUSTRUP
Bjarne Stroustrup, C++'ın tasarımcısı ve orijinal uygulayıcısı ve yazarıdır.
C++ Programlama Dilinin Tarihi ve C++'ın Tasarımı ve Evrimi. Onun
araştırma ilgi alanları arasında dağıtık sistemler, simülasyon, tasarım, programlama ve
Programlama dilleri. Dr. Stroustrup, Mühendislik Fakültesi Profesörüdür.
Texas A&M Üniversitesi'nde Bilgisayar Bilimi. ANSI/ISO'da aktif olarak yer almaktadır.
C++ standardizasyonu. AT&T'de yirmi yılı aşkın bir sürenin ardından,
AT&T Labs, Bilgi ve Yazılım Sistemleri üyesi olarak araştırma yapıyor
Araştırma Laboratuvarı ACM Üyesi, AT&T Bell Laboratuvarları Üyesi ve
AT&T Üyesi. 1993 yılında Stroustrup, ACM Grace Murray Hopper Ödülü'nü aldı.
“C++ programlama dilinin temellerini atan ilk çalışmaları için. Temelli
temelleri ve Dr. Stroustrup'un devam eden çabaları üzerine C++,
bilgi işlem tarihindeki en etkili programlama dilleri.”
PROGRAMLAMA PARADİGmaları
Nesne yönelimli paradigma hakkındaki düşünceleriniz:
Artıları ve eksileri. önce ne dediğimi söyleyeyim
OOP ile kastedilen—çok fazla insan “nesne-
odaklı” basitçe “iyi” ile eşanlamlıdır. Eğer öyleyse, orada
başka paradigmalara gerek kalmazdı. OO'nun anahtarı
polimorfik sağlayan sınıf hiyerarşilerinin kullanılmasıdır.
sanal bazı kaba eşdeğer yoluyla davranış
fonksiyonlar. Uygun OO için kaçınmak önemlidir
bu tür bir hiyerarşide verilere doğrudan erişilmesi ve
yalnızca iyi tasarlanmış işlevsel bir arayüz kullanın.
İyi belgelenmiş güçlü yönlerine ek olarak,
nesne yönelimli programlamanın da bariz zayıf-
neseler. Özellikle, her konsept doğal olarak uymuyor
bir sınıf hiyerarşisine ve bunu destekleyen mekanizmalara
nesne yönelimli programlama önemli
alternatiflerle karşılaştırıldığında genel giderler. birçok basit için
soyutlamalar, hiyerarşilere dayanmayan sınıflar
ve çalışma zamanı bağlaması daha basit ve daha fazlasını sağlar
verimli alternatif. Ayrıca, çalışma süresinin olmadığı durumlarda
çözünürlük gereklidir, genel programlamaya dayalı
(derleme zamanı) parametrik polimorfizm daha iyidir
davranışlı ve daha verimli bir yaklaşımdır.
Yani, C++: OO mu yoksa başka mı? C++ birkaç
paradigmalar—OOP, genel programlama ve
prosedürel programlama ve bunların kombinasyonları
paradigmalar çok paradigma programlamayı şu şekilde tanımlar:
birden fazla programlama stilini destekleme (“para-
digm”) ve bu stillerin kombinasyonları.
Mini bir çoklu paradigma örneğiniz var mı?
programlama? Klasikin bu varyantını düşünün
"şekillerin toplanması" örnekleri (kökenli
nesneyi destekleyen ilk dilin ilk günleri
odaklı programlama: Simula 67):
void draw_all( const vektör<Şekil*>& vs)
{
for ( int i = 0; i<vs.size(); ++i)
vs[i]->draw();
}
Burada, genel kap vektörünü birlikte kullanıyorum
polimorfik tip Shape ile . vektör
statik tip güvenliği ve optimum çalışma süresi sağlar.
biçim. Şekli işleme yeteneği sağlar
a Shape (yani, bir sınıfın herhangi bir nesnesinden türetilen
Şekil ) yeniden derleme olmadan.
536

Sayfa 558
Bunu herhangi bir kapsayıcıya kolayca genelleyebiliriz.
C++ standart kitaplık gereksinimlerini karşılar:
şablon <sınıf C>
void draw_all( const C&c)
{
typedef typename C::
const_iterator CI;
için (CI p = c.begin ();
p!=c.end(); ++p)
(*p)->çiz();
}
Yineleyicileri kullanmak, bu draw_all () öğesini uygulamamıza izin verir.
gibi abonelikleri desteklemeyen kapsayıcılara
standart kütüphane listesi:
vektör<Şekil*> vs;
list<Şekil*> ls;
// . . .
draw_all(vs);
draw_all(ls);
Hatta bunu herhangi bir durumu ele almak için daha da genelleştirebiliriz.
bir çift yineleyici tarafından tanımlanan öğe dizisi:
şablon <class Yineleyici> geçersiz
draw_all(Yineleyici b, Yineleyici e)
{
for_each(b,e,mem_fun(&Shape::draw));
}
Uygulamayı basitleştirmek için standardı kullandım
kitaplık algoritması for_each .
Bu son draw_all () sürümünü şu şekilde adlandırabiliriz :
standart bir kitaplık listesi ve bir dizi:
list<Şekil*> ls;
Şekil* olarak[100];
// . . .
draw_all(ls.begin(),ls.end());
draw_all(as,as+100);
“DOĞRU” DİLİ SEÇMEK
İŞ İÇİN
Bu arka plana sahip olmak ne kadar yararlıdır?
sayısız paradigmalar? yoksa daha mı iyi olurdu
daha da aşina olmak için zaman ayırın
bunları öğrenmek yerine OO dilleriyle
diğer paradigmalar? olan herkes için gereklidir
alanlarında profesyonel olarak kabul edilmek istiyor.
birkaç dil bilmek için yazılım ve birkaç
programlama paradigmaları Şu anda, C++ en iyisidir
çok paradigmalı programlama dili ve
çeşitli biçimlerini öğrenmek için iyi bir dil
programlama. Ancak, bilmek iyi bir fikir değil
sadece C++, tek bir paradigmayı bilmek şöyle dursun
dilim. Bu biraz renk körü olmak gibi olurdu ya da
monoglot: Ne yaptığınızı pek bilemezdiniz
kayıptı. İyiliğe ilham veren çoğu şey
programlama öğrenmekten gelir ve
birkaç programlama stilini takdir etti ve görüldü
farklı dillerde nasıl kullanılabileceğini.
Ayrıca, olmayan herhangi bir programlamayı düşünüyorum.
Önemsiz program, sağlam ve sağlam profesyoneller için bir iş
acelesi olan insanlar için değil, geniş bir eğitim
ve dar "eğitim".
537

Sayfa 559
538
Bölüm 12 Nesne Yönelimli Programlama Desteği
Smalltalk'ın dinamik bağlaması, tür hatalarının çalıştırılana kadar algılanmamasını sağlar
zaman. Var olmayan yöntemlere mesajlar içeren bir program yazılabilir.
ve mesajlar gönderilene kadar algılanmayacak, bu da büyük bir soruna neden oluyor.
geliştirmede daha sonra statik tipte bir hatadan daha fazla hata onarımı
dilim. Ancak uygulamada tip hataları ciddi bir problem değildir.
Küçük konuşma programları.
Genel olarak, Smalltalk'ın tasarımı sürekli olarak
dil zarafeti ve nesne yönelimli ilkelere sıkı sıkıya bağlılık
özellikle pratik konulara bakılmaksızın, programlama desteği
yürütme verimliliği. Bu, nesnelerin özel kullanımında en belirgindir ve
tipsiz değişkenler.
Smalltalk kullanıcı arayüzünün bilgi işlem üzerinde önemli bir etkisi oldu:
Pencerelerin, fareyle işaretleme aygıtlarının ve açılır pencerelerin ve açılan pencerelerin entegre kullanımı
Hepsi ilk olarak Smalltalk'ta ortaya çıkan aşağı menüler, çağdaş
yazılım sistemleri.
Smalltalk'ın belki de en büyük etkisi, nesne yönelimli teknolojinin gelişmesidir.
programlama, artık en yaygın kullanılan tasarım ve kodlama metodolojisidir.
12.5 C++'da Nesne Yönelimli Programlama Desteği
Bölüm 2, C++'ın tasarımla birlikte C ve SIMULA 67'den nasıl geliştiğini açıklar.
neredeyse iletişimi korurken nesne yönelimli programlama için destek hedefi
desteklemek için kullanıldıkları için C. C++ sınıflarıyla tam geriye dönük uyumluluk
soyut veri türleri, Bölüm 11'de tartışılmaktadır.
Bu bölümde nesne yönelimli programlamanın temelleri incelenmektedir. bu
C++ sınıflarının, kalıtımın ve dinamik bağlamanın tüm ayrıntılarının toplanması
büyük ve karmaşıktır. Bu bölümde yalnızca en önemlileri tartışılmaktadır.
bu konular, özellikle, açıklanan tasarım sorunlarıyla doğrudan ilgili olanlar
Bölüm 12.3'te.
C++, yaygın olarak kullanılan ilk nesne yönelimli programlama diliydi ve
hala en popülerler arasında. Yani, doğal olarak, diğerlerinin birlikte olduğu kişidir.
ölçüler genellikle karşılaştırılır. Bu iki nedenden dolayı, buradaki C++ kapsamımız
bu bölümde tartışılan diğer örnek dillerden daha ayrıntılı.
12.5.1 Genel Özellikler
C ile geriye dönük uyumluluğu sağlamak için C++, C'nin tür sistemini korur
ve ona sınıflar ekler. Bu nedenle, C++ hem geleneksel zorunluluk diline sahiptir
Nesne yönelimli bir dilin türleri ve sınıf yapısı. Yöntemleri destekler,
belirli sınıflarla ilgili olmayan işlevlerin yanı sıra. Bu onu bir hibrit yapar
dil, hem prosedürel programlamayı hem de nesne yönelimli
programlama.
C++ nesneleri statik, yığın dinamik veya yığın dinamik olabilir. Açık
yığın dinamik nesneler için silme operatörünü kullanarak serbest bırakma gereklidir,
çünkü C++ örtük depolama ıslahını içermez.

Sayfa 560
12.5 C++ 539'da Nesne Yönelimli Programlama Desteği
Birçok sınıf tanımı, örtük olarak bir yıkıcı yöntemi içerir.
sınıfın bir nesnesinin varlığı sona erdiğinde çağrılır. Yıkıcı için kullanılır
veri üyeleri tarafından başvurulan yığınla ayrılmış belleği serbest bırakın. Olabilir
ayrıca nesnenin ölmeden hemen önceki durumunun bir kısmını veya tamamını kaydetmek için kullanılabilir,
genellikle hata ayıklama amacıyla.
12.5.2 Kalıtım
Bir C++ sınıfı, daha sonra onun ebeveyni olan mevcut bir sınıftan türetilebilir,
veya temel, sınıf. Smalltalk ve destekleyen diğer dillerin çoğundan farklı olarak
nesne yönelimli programlama, bir C++ sınıfı da bağımsız olabilir.
bir süper sınıf.
Bir sınıf tanımında tanımlanan verilere veri üyeleri denildiğini hatırlayın.
o sınıfın ve bir sınıf tanımında tanımlanan işlevlere üye denir.
fonksiyonlar bu sınıfın (Diğer dillerde üye fonksiyonları genellikle denir
yöntemler). Temel sınıfın üyelerinin bir kısmı veya tamamı, sınıf tarafından miras alınabilir.
yeni üyeler ekleyebilen ve miras alınan üyeyi değiştirebilen türetilmiş sınıf
fonksiyonlar.
Tüm C++ nesneleri kullanılmadan önce başlatılmalıdır. Bu nedenle, tüm C++
sınıflar, veri üyelerini başlatan en az bir yapıcı yöntemi içerir
yeni nesnenin Yapıcı yöntemleri, bir nesne bir nesne olduğunda örtük olarak çağrılır.
yaratıldı. Veri üyelerinden herhangi biri yığınla ayrılmış verilere işaret ediyorsa,
yapıcı bu depolamayı tahsis eder.
Bir sınıfın bir ebeveyni varsa, devralınan veri üyeleri şu durumlarda başlatılmalıdır:
alt sınıf nesnesi oluşturulur. Bunu yapmak için, ana kurucu dolaylı olarak
aranan. Başlatma verilerinin ana kurucuya sağlanması gerektiğinde,
alt sınıf nesne oluşturucusuna yapılan çağrıda verilir. Genel olarak bu yapılır
aşağıdaki yapı ile:
alt sınıf ( alt sınıf parametreleri ): parent_class ( üst sınıf parametreleri ) {
. . .
}
Bir sınıf tanımına hiçbir kurucu dahil edilmemişse, derleyici bir
önemsiz kurucu. Bu varsayılan kurucu, ebeveynin kurucusunu çağırır.
sınıf, eğer bir üst sınıf varsa.
Sınıf üyeleri özel, korumalı veya genel olabilir. Özel üyeler
yalnızca üye işlevler ve sınıfın arkadaşları tarafından erişilebilir. Her iki fonksiyon
ve sınıflar bir sınıfın arkadaşı olarak ilan edilebilir ve böylece erişim verilebilir
özel üyelerine. Herkese açık üyeler her yerde görülebilir. Korumalı
üyeler, erişimi olan türetilmiş sınıflar dışında özel üyeler gibidir.
devamında anlatılmaktadır. Türetilmiş sınıflar, devralınanları için erişilebilirliği değiştirebilir
üyeler. Türetilmiş bir sınıfın sözdizimsel biçimi
sınıf türetilmiş_sınıf_adı : türetme_modu temel_sınıf_adı
{ veri üyesi ve üye işlevi bildirimleri };

Sayfa 561
540
Bölüm 12 Nesne Yönelimli Programlama Desteği
derivation_mode, public veya private olabilir . 5 (Karıştırmayın
kamu ve özel üyelerle genel ve özel türetme.) Kamu
ve bir temel sınıfın korumalı üyeleri de geneldir ve korunur,
genel olarak türetilmiş bir sınıfta. Özel türetilmiş bir sınıfta, hem genel
ve temel sınıfın korumalı üyeleri özeldir. Yani, bir sınıf hiyerarşisinde,
Özel - tüm atası sınıflarının tüm üyelerine erişim kapalı türetilmiş sınıf keser
tüm ardıl sınıflara ve korunan üyelere erişebilir veya erişemeyebilir.
sonraki alt sınıflara uygulanabilir (birinciyi geçerek). Bir üssün özel üyeleri
sınıf türetilmiş bir sınıf tarafından miras alınır, ancak üyeler tarafından görülmezler.
türetilmiş sınıfın ve bu nedenle orada hiçbir faydası yoktur. Özel türevler
bir alt sınıfın farklı üyelere sahip olma olasılığını sağlamak
üst sınıftaki aynı üyelerden daha fazla erişim. Aşağıdakileri göz önünde bulundur
örnek:
sınıf temel_sınıf {
özel :
int a;
yüzer x;
korumalı :
int b;
yüzer y;
kamu :
int c;
yüzer z;
};
class subclass_1 : public base_class {. . .};
class subclass_2 : özel base_class {. . .};
Gelen subclass_1 , b ve y korunurlar ve c ve Z halka açıktır. In subclass_2 ,
b , y , c ve z özeldir. Hiçbir türetilmiş subclass_2 sınıfının üyesi olamaz
base_class herhangi bir üyesine erişim ile . Veri üyeleri , bir ve x de
base_class , subclass_1 veya subclass_2 içinde erişilebilir değildir .
Özel türetilmiş alt sınıfların alt türler olamayacağına dikkat edin. Örneğin,
temel sınıfın bir genel veri üyesi varsa, o verinin özel türetilmesi altında
üye alt sınıfta özel olacaktır. Bu nedenle, eğer alt nesnenin bir nesnesi
sınıf, temel sınıfın bir nesnesi için ikame edildi, bu verilere erişim
üye, alt sınıf nesnesinde geçersiz olur. Bu bir ilişki
kırılmak.
Özel sınıf türetme altında, üst sınıfın hiçbir üyesi örtük olarak
türetilmiş sınıfın örnekleri tarafından görülebilir. Yapılması gereken herhangi bir üye
görünür türetilmiş sınıfta yeniden dışa aktarılmalıdır. Bu yeniden ihraç
türetme özel olsa bile bir üyeyi gizlenmekten muaf tutar.
Örneğin, aşağıdaki sınıf tanımını göz önünde bulundurun:
5. Aynı zamanda korunabilir , ancak bu seçenek burada tartışılmamaktadır.

Sayfa 562
12.5 C++ 541'de Nesne Yönelimli Programlama Desteği
class subclass_3 : özel base_class {
base_class :: c;
. . .
}
Artık subclass_3 örnekleri c'ye erişebilir . Bildiğim kadarıyla c ilgilidir, bu sanki olduğunu
türetme halka açık olmuştu. Bu sınıf tanımındaki çift ​​kolon ( :: )
bir kapsam çözümleme operatörüdür. Aşağıdaki varlığın bulunduğu sınıfı belirtir.
tanımlanmış.
Aşağıdaki paragraflardaki örnek, amacı ve kullanımı göstermektedir.
özel türetme.
Aşağıdaki C++ kalıtım örneğini göz önünde bulundurun.
bağlantılı liste sınıfı tanımlanır ve daha sonra iki kullanışlı alt sınıfı tanımlamak için kullanılır:
sınıf single_linked_list {
özel :
sınıf düğümü {
kamu :
düğüm *bağlantısı;
int içeriği;
};
düğüm * kafa;
kamu :
single_linked_list() {kafa = 0};
geçersiz insert_at_head( int );
geçersiz insert_at_tail( int );
int remove_at_head();
int boş();
};
Yuvalanmış sınıf, node , bağlantılı listenin bir hücresini bir tam sayıdan oluşacak şekilde tanımlar.
değişken ve bir düğüm nesnesine işaretçi . Düğüm sınıfı, özel maddesi olan
bu da onu diğer tüm sınıflardan gizler. Ancak üyeleri halka açıktır, bu nedenle
yuvalama sınıfı single_linked_list tarafından görülebilir . Özel olsaydı,
node'un onları görünür kılmak için yuvalama sınıfını bir arkadaş olarak ilan etmesi gerekir.
yuvalama sınıfında. Yuvalanmış sınıfların üyelere özel erişimi olmadığını unutmayın.
yuvalama sınıfının. Yalnızca yuvalama sınıfının statik veri üyeleri tarafından görülebilir
iç içe sınıfın yöntemleri. 6
Çevreleyen sınıf, single_linked_list , yalnızca tek bir veri belleğine sahiptir.
ber, listenin başlığı olarak işlev görecek bir işaretçi. Bir yapıcı işlevi içerir,
sadece head değerini boş gösterici değerine ayarlar . Dört üye işlevi izin verir
6. Bir sınıf, bir yuvalama sınıfının yönteminde de tanımlanabilir. Bu tür sınıfların kapsam kuralları
yerel değişkenler için bile, doğrudan diğer sınıflarda iç içe geçmiş sınıflarla aynıdır
tanımlandıkları yöntemde bildirilir.

Sayfa 563
542
Bölüm 12 Nesne Yönelimli Programlama Desteği
bir liste nesnesinin her iki ucuna eklenecek düğümler, kaldırılacak düğümler
bir listenin bir ucu ve boş olup olmadığı test edilecek listeler.
Aşağıdaki tanımlar, her ikisi de aşağıdakilere dayalı olarak yığın ve kuyruk sınıfları sağlar:
single_linked_list sınıfı:
sınıf yığını: genel single_linked_list {
kamu :
yığın() {}
void push( int değeri) {
insert_at_head(değer);
}
int pop() {
dönüş ) (remove_at_head;
}
};
sınıf kuyruğu: genel single_linked_list {
kamu :
sıra() {}
geçersiz kuyruğa alma( int değeri) {
insert_at_tail(değer);
}
int dequeue() {
remove_at_head();
}
};
Her iki nesneleri Not yığını ve sıra alt sınıfları erişebilir
temel sınıfta tanımlanan boş işlev, single_linked_list (çünkü
halka açık bir türetmedir). Her iki alt sınıf da yapıcı işlevleri tanımlar.
hiçbir şey yapma. Bir alt sınıfın nesnesi oluşturulduğunda, uygun yapı
alt sınıfta tor dolaylı olarak çağrılır. Ardından, geçerli herhangi bir kurucu
temel sınıf denir. Örneğimizde, yığın türünde bir nesne
oluşturulduğunda, hiçbir şey yapmayan yığın oluşturucusu çağrılır. Sonra
single_linked_list içindeki yapıcı çağrılır, bu gerekli olanı yapar
başlatma.
Yığın ve sıra sınıflarının her ikisi de aynı ciddi sorundan muzdarip:
Her ikisinin de istemcileri, üst sınıfın tüm genel üyelerine erişebilir,
single_linked_list . Bir yığın nesnesinin istemcisi insert_at_'ı çağırabilir
tail , böylece yığınının bütünlüğünü yok eder. Aynı şekilde, bir müşteri
kuyruk nesnesi insert_at_head'i çağırabilir . Bu istenmeyen erişimler
çünkü hem izin yığın ve kuyruk alt tipleri olan single_linked_
liste . Alt sınıfın miras almasını istediği yerde genel türetme kullanılır.
temel sınıfın tüm arayüzü. Alternatif, türetmeye izin vermektir
alt sınıfın yalnızca temel sınıfın uygulamasını devraldığı. Bizim
alt türleri olmamak için iki örnek türetilmiş sınıf yazılabilir.

Sayfa 564
12.5 C++ 543'te Nesne Yönelimli Programlama Desteği
public türetme yerine private türetme kullanarak ebeveyn sınıfı . 7 O zaman hem
Ayrıca boş yeniden dışa aktarmanız gerekecek , çünkü onların
örnekler. Bu durum, özel türetme için motivasyonu göstermektedir.
seçenek. stack_2 adlı yığın ve kuyruk türlerinin yeni tanımları
ve tail_2 , aşağıda gösterilmiştir:
class stack_2 : özel single_linked_list {
kamu :
stack_2() {}
void push( int değeri) {
single_linked_list :: insert_at_head(değer);
}
int pop() {
dönüş ) (single_linked_list :: remove_at_head;
}
single_linked_list:: boş();
};
sınıf kuyruğu_2: özel single_linked_list {
kamu :
kuyruk_2() {}
geçersiz kuyruğa alma( int değeri) {
single_linked_list :: insert_at_tail(değer);
}
int dequeue() {
single_linked_list :: remove_at_head();
}
single_linked_list:: boş();
};
Bu iki sınıfın, temel sınıfa erişime izin vermek için yeniden dışa aktarmayı kullandığına dikkat edin.
Müşteriler için yöntemler. Kamusal türetme kullanıldığında bu gerekli değildi.
Yığın ve kuyruğun iki versiyonu alt arasındaki farkı gösterir.
alt türler olmayan türler ve türetilmiş türler. Bağlantılı liste bir genellemedir
her ikisi de bağlantılı listeler olarak uygulanabileceğinden, hem yığınlar hem de kuyruklar. Böyle,
yığın ve kuyruk sınıflarını tanımlamak için bağlantılı liste sınıfından miras almak doğaldır.
Bununla birlikte, ikisi de bağlantılı liste sınıfının bir alt türü değildir, çünkü her ikisi de
ana sınıfın genel üyeleri private, bu da onları erişilemez hale getirir.
müşteriler.
Arkadaşların gerekli olmasının nedenlerinden biri, bazen bir alt programın
iki farklı sınıfın üyelerine erişebilecek şekilde yazılmalıdır. İçin
örneğin, bir programın vektörler için bir sınıf ve matrisler için bir sınıf kullandığını varsayalım ve
bir vektör nesnesini bir matris nesnesi ile çarpmak için bir alt program gereklidir. İçinde
C++, çarpma işlevi her iki sınıfın da dostu olabilir.
7. Alt tür olmazlar çünkü ana sınıfın genel üyeleri bir
istemci, ancak bu üyelerin özel olduğu alt sınıfın bir istemcisinde değil.

Sayfa 565
544
Bölüm 12 Nesne Yönelimli Programlama Desteği
C++, birden fazla sınıfın olmasına izin veren çoklu kalıtım sağlar.
yeni bir sınıfın ebeveyni olarak adlandırılır. Örneğin, bir sınıf istediğimizi varsayalım.
Şekil çizmek için yazılmış bir sınıfın davranışına ihtiyaç duyan çizim ve
ayrı bir iş parçacığında çalıştırmak için gereken yeni sınıfın yöntemleri. tanımlayabiliriz
devamındaki:
sınıf Konu { . . . };
sınıf Çizimi { . . . };
class DrawThread : public Thread, public Drawing { . . . };
Sınıf DrawThread hem üyelerinin tüm devralır Konu ve sığama
ing . Her iki takdirde Konu ve Çizim aynı sahip üyeleri başına
ad, DrawThread sınıfının nesnelerinde açık bir şekilde başvurulabilirler.
kapsam çözümleme operatörünü kullanarak ( :: ). Bu çoklu miras örneği
tans Şekil 12.5'te gösterilmektedir.
Çoklu kalıtımın C++ uygulamasıyla ilgili bazı sorunlar şunlardır:
Bölüm 12.11'de tartışılmıştır.
C++'daki geçersiz kılma yöntemleri tam olarak aynı parametre profiline sahip olmalıdır
geçersiz kılınan yöntem olarak. Parametre profillerinde farklılık varsa,
alt sınıftaki yöntem, ilgili olmayan yeni bir yöntem olarak kabul edilir.
ata sınıfında aynı ada sahip yöntem. dönüş türü
geçersiz kılma yöntemi, geçersiz kılınan yöntemle aynı olmalıdır
veya geçersiz kılınan yöntemin dönüş türünün genel olarak türetilmiş bir türü olmalıdır.
12.5.3 Dinamik Bağlama
Buraya kadar tanımladığımız üye fonksiyonların tümü statik olarak bağlıdır;
yani bunlardan birine yapılan bir çağrı statik olarak bir fonksiyon tanımına bağlıdır. bir C++
nesne, bir işaretçi yerine bir değer değişkeni aracılığıyla manipüle edilebilir veya
referans. (Böyle bir nesne statik veya yığın dinamik olacaktır.) Ancak, bu durumda
durumda, nesnenin türü bilinir ve statiktir, bu nedenle dinamik bağlama gerekli değildir.
Öte yandan, temel sınıf tipine sahip bir işaretçi değişkeni
halka açık olarak türetilen herhangi bir sınıfın yığın dinamik nesnelerine işaret etmek için kullanılır
bu temel sınıf, onu polimorfik bir değişken haline getirir. Genel olarak türetilmiş alt sınıflar
Şekil 12.5
Çoklu kalıtım
İplik
Drawİplik
Resim çizme

Sayfa 566
12.5 C++ 545'te Nesne Yönelimli Programlama Desteği
temel sınıfın üyelerinden hiçbiri özel değilse alt türlerdir. özel olarak
türetilmiş alt sınıflar asla alt tür değildir. Bir temel sınıfa işaretçi kullanılamaz
alt tür olmayan bir alt sınıfta bir yönteme başvurmak için.
C++ değer değişkenlerine izin vermez (işaretçilerin veya referansların aksine)
polimorfik olmak. Bir üyeyi çağırmak için polimorfik bir değişken kullanıldığında
türetilmiş sınıflardan birinde geçersiz kılınan işlev, çağrı dinamik olarak yapılmalıdır
doğru üye işlevi tanımına bağlı. olması gereken üye işlevleri
dinamik olarak bağlı olmak, sanal işlevler olarak bildirilmelidir.
Ayrılmış kelime ile onların başlıkları sanal yalnızca a görünebilir,
sınıf vücut.
Adında bir temel sınıf olma durumu göz önünde bulundurun Şekli a ile birlikte
Daireler, dikdörtgenler gibi farklı şekil türleri için türetilmiş sınıflar topluluğu.
açılar ve benzeri. Bu şekillerin görüntülenmesi gerekiyorsa, görüntülenen
üye işlevi, çizim , her alt öğe veya şekil türü için benzersiz olmalıdır.
Bu beraberlik versiyonları sanal olarak tanımlanmalıdır. Beraberlik çağrısı yapıldığında
türetilmiş sınıfların temel sınıfına bir işaretçi ile yapılan bu çağrının
doğru türetilmiş sınıfın üye işlevine dinamik olarak bağlıdır. bu
aşağıdaki örnek, az önce açıklanan örnek duruma ilişkin tanımlara sahiptir:
sınıf Şekil {
kamu :
sanal boşluk çizimi() = 0;
. . .
};
sınıf Çember : genel Şekil {
kamu :
geçersiz çizim() { . . . }
. . .
};
class Rectangle : public Shape {
kamu :
geçersiz çizim() { . . . }
. . .
};
sınıf Kare : genel Dikdörtgen {
kamu :
geçersiz çizim() { . . . }
. . .
};
Bu tanımlar göz önüne alındığında, aşağıdaki kod hem statik hem de
dinamik olarak bağlı çağrılar:
Kare* kare = yeni Kare;
Dikdörtgen* dikdörtgen = yeni Dikdörtgen;
Şekil* ptr_shape;

Sayfa 567
546
Bölüm 12 Nesne Yönelimli Programlama Desteği
ptr_shape = kare;
// Şimdi ptr_shape bir
// Kare nesne
ptr_shape->draw(); // Beraberliğe dinamik olarak bağlı
// Square sınıfında
rect->draw();
// Statik olarak çekilişe bağlı
// Rectangle sınıfında
Bu durum Şekil 12.6'da gösterilmektedir.
O Bildirimi beraberlik taban sınıfı tanımında fonksiyon şekli kümesidir
0'a. Bu özel sözdizimi, bu üye işlevin saf olduğunu belirtmek için kullanılır.
sanal işlev , yani gövdesi yoktur ve çağrılamaz. Olmalı
işlevi çağırırlarsa türetilmiş sınıflarda yeniden tanımlanır. Saf bir sanalın amacı
işlev, bir işlevin arayüzünü, herhangi bir uygulamasından vermeden sağlamaktır.
mental aktivite. Saf sanal işlevler genellikle gerçek bir üye olduğunda tanımlanır.
Şekil 12.6
dinamik bağlama
Şekil
sanal boşluk çekilişi ( ) = 0
Dikdörtgen
Dikdörtgen
Dikdörtgen*
Meydan
nesneler
Meydan*
Sınıf Hiyerarşisi
bağlamalar
Türler
işaretçiler
metrekare
doğru
Şekil*
geçersiz çekiliş ( ) { ... }
geçersiz çekiliş ( ) { ... }
geçersiz çekiliş ( ) { ... }
geçersiz çekiliş ( ) { ... }
geçersiz çekiliş ( ) { ... }
Daire
ptr_shape
Meydan

Sayfa 568
12.5 C++ 547'de Nesne Yönelimli Programlama Desteği
temel sınıftaki işlev yararlı olmaz. Bölüm 12.2.3'te bir baz olduğunu hatırlayın.
sınıf Bina tartışıldı ve her alt sınıf belirli bir tür tanımladı.
bina. Her alt sınıfın bir çekme yöntemi vardı, ancak bunların hiçbiri
temel sınıf. Bu nedenle, çizim , Building sınıfında saf bir sanal işlev olacaktır .
Saf bir sanal işlev içeren herhangi bir sınıf, soyut bir sınıftır . İçinde
C++, soyut bir sınıf, ayrılmış bir sözcükle işaretlenmez. soyut bir sınıf
tamamen tanımlanmış yöntemleri içerebilir. Bir özeti başlatmak yasa dışıdır
sınıf. Kesin anlamda, soyut bir sınıf, yalnızca sınıfı temsil etmek için kullanılan sınıftır.
bir türün özellikleri. C++, bunları gerçekten modellemek için soyut sınıflar sağlar
soyut sınıflar. Soyut bir sınıfın alt sınıfı saf sanal sınıfı yeniden tanımlamıyorsa
üst sınıfının işlevi, bu işlev saf bir sanal işlev olarak kalır.
alt sınıf ve alt sınıf da soyut bir sınıftır.
Soyut sınıflar ve kalıtım birlikte güçlü bir tekniği destekler.
yazılım geliştirme. Türlerin hiyerarşik olarak tanımlanmasına izin verirler, böylece
ilgili türler, ortak türlerini tanımlayan gerçekten soyut türlerin alt sınıfları olabilir.
soyut özellikler.
Dinamik bağlama, draw gibi üyeleri kullanan kodun yazılmasına izin verir.
çekilişin tüm versiyonları veya hatta herhangi biri yazılmadan önce. Yeni türetilmiş
sınıflar, kodda herhangi bir değişiklik gerektirmeden yıllar sonra eklenebilir
bu tür dinamik olarak bağlı üyeleri kullanan. Bu son derece kullanışlı bir özelliktir
nesne yönelimli diller.
Yığın dinamik nesneler için referans atamaları işaretçiden farklıdır
yığın dinamik nesneler için atamalar. Örneğin, aşağıdakileri göz önünde bulundurun
son örnekle aynı sınıf hiyerarşisini kullanan kod:
Kare kare;
// Yığın üzerinde bir Square nesnesi tahsis edin
dikdörtgen dikdörtgen; // Bir Rectangle nesnesi tahsis et
// yığın
doğru = metrekare;
// Veri üyesi değerlerini şuradan kopyalar
// Square nesnesi
rect.draw(); // Beraberliği Dikdörtgenden çağırır
// nesne
rect = sq atamasında , tarafından başvurulan nesneden üye verileri
sq , rect tarafından başvurulan nesnenin veri üyelerine atanır ,
ancak rect yine de Rectangle nesnesine başvurur . Bu nedenle, çağrı
rect tarafından başvurulan nesneyi çizmek , Dikdörtgeninki olacaktır.
sınıf. Eğer rect ve sq yığın dinamik nesnelere işaretçilerse, aynı atama-
ment kılacak bir işaretçi atama olacağını rect 'ın
Kare nesne ve bir çağrı çizmek yoluyla rect'in dinamik bağlı olacağını
için beraberlik içinde Kare nesne.
12.5.4 Değerlendirme
C++'ın nesne yönelimli özelliklerini Küçük'ünkilerle karşılaştırmak doğaldır.
konuşmak. C++'ın mirası, terimler açısından Smalltalk'ınkinden daha karmaşıktır.
erişim kontrolü. Her iki erişim denetimini de sınıf tanımı içinde kullanarak

Sayfa 569
548
Bölüm 12 Nesne Yönelimli Programlama Desteği
ve türetme erişim kontrolleri ve ayrıca arkadaş işlevlerinin olasılığı
ve sınıflar, C++ programcısı, erişim üzerinde son derece ayrıntılı kontrole sahiptir.
sınıf üyeleri. C++ çoklu kalıtım sağlar ve Smalltalk sağlar
hayır, bunun C++ için bir avantaj olmadığını düşünen birçok kişi var. Dezavantajları
çoklu kalıtımın değeri karşısında ağır basar. Aslında, C++ tek
çoklu kalıtımı destekleyen bu bölümde tartışılan dil. Üzerinde
diğer yandan, çoklu mirasa alternatifler sağlayan diller, örneğin
Objective-C, Java ve C#, bu alanda Smalltalk'a göre açıkça bir avantaja sahiptir.
C++'da programcı statik bağlama veya dinamik bağlamayı belirleyebilir.
bağlayıcı kullanılacaktır. Statik bağlama daha hızlı olduğundan, bu bir avantajdır.
dinamik bağlamanın gerekli olmadığı durumlar. Ayrıca, hatta
C++'daki dinamik bağlama, Smalltalk ile karşılaştırıldığında hızlıdır.
C++'da bir sanal üye işlev çağrısını bir işlev tanımına bağlamanın bir
sabit maliyet, kalıtım hiyerarşisinde tanım ne kadar uzak olursa olsun
görünür. Sanal işlevlere yapılan çağrılar yalnızca beş bellek referansı daha gerektirir
statik olarak bağlı çağrılardan daha fazladır (Stroustrup, 1988). Ancak Smalltalk'ta mesajlar
her zaman dinamik olarak yöntemlere bağlıdır ve kalıtımda ne kadar uzaksa
tans hiyerarşisi doğru yöntem, daha uzun sürer. dezavantajı
kullanıcının hangi bağlamaların statik ve hangilerinin dinamik olduğuna karar vermesine izin vermek
orijinal tasarımın, alınması gerekebilecek bu kararları içermesi gerektiğidir.
sonradan değişti.
C++'ın statik tip denetimi, Smalltalk'a göre bir avantajdır.
tip denetimi dinamiktir. Mesajlarla bir Smalltalk programı yazılabilir.
program çalıştırılana kadar keşfedilmeyen var olmayan yöntemler.
Bir C++ derleyicisi bu tür hataları bulur. Derleyici tarafından algılanan hatalar daha ucuzdur
testte bulunanlardan daha tamir etmek için.
Smalltalk esasen tipsizdir, yani tüm kodlar etkin bir şekilde geneldir.
Bu, büyük bir esneklik sağlar, ancak statik tip denetimi feda edilir. C++
şablon tesisi aracılığıyla genel sınıflar sağlar (Bölüm 11'de açıklandığı gibi),
hangi statik tip kontrolünün faydalarını korur.
Smalltalk'ın birincil avantajı, zarafeti ve sadeliğinde yatmaktadır.
tasarımının tek felsefesinden kaynaklanan dil. tamamen
ve tamamen nesne yönelimli paradigmaya adanmış, ödün vermeden
Yerleşik bir kullanıcı tabanının kaprislerinin gerektirdiği hatalar. C++, diğer yandan
temeli olarak tek bir felsefeye sahip olmayan geniş ve karmaşık bir dildir.
nesne yönelimli programlamayı desteklemek ve C kullanıcısını dahil etmek dışında
temel. En önemli hedeflerinden biri, verimliliği ve lezzeti korumaktı.
C'nin nesne yönelimli programlama avantajlarını sağlarken. Bazı
insanlar bu dilin özelliklerinin her zaman birbirine tam olarak uymadığını ve
karmaşıklığın en azından bir kısmının gereksiz olduğunu.
Chambers ve Ungar'a (1991) göre, Smalltalk belirli bir diziyi çalıştırdı.
optimize edilmiş C hızının yalnızca yüzde 10'unda küçük C tarzı kıyaslama testleri.
C++ programları, eşdeğer C programlarından yalnızca biraz daha fazla zaman gerektirir
(Stroustrup, 1988). Smalltalk ve C++ arasındaki büyük verimlilik farkı göz önüne alındığında,
C++'ın ticari kullanımının, C++'dan çok daha yaygın olması şaşırtıcı değildir.
Smalltalk'a ait. Bu farkta başka faktörler de vardır, ancak verimlilik

Sayfa 570
12.6 Objective-C 549'da Nesne Yönelimli Programlama Desteği
açıkça C++ lehine güçlü bir argüman. Tabii ki, derlenen tüm lan-
nesne yönelimli programlamayı destekleyen göstergeler yaklaşık 10 kat
Smalltalk'tan daha hızlı.
12.6 Objective-C'de Nesne Yönelimli Programlama Desteği
Objective-C göreli olarak nesne yönelimli programlama desteğini tartışıyoruz
C++'a göre. Bu iki dil yaklaşık olarak aynı şekilde tasarlanmıştır.
zaman. Her ikisi de C diline nesne yönelimli programlama desteği ekler. İçinde
görünüm, en büyük fark yöntem çağrılarının sözdizimindedir; C++
C'nin işlev çağrılarıyla yakından ilişkilidir, oysa Objective-C'de bunlar
Smalltalk'ın yöntem çağrılarına daha çok benzer.
12.6.1 Genel Özellikler
Objective-C, C# gibi hem ilkel türlere hem de nesnelere sahiptir. bir sınıf olduğunu hatırla
tanım, arayüz ve uygulama olmak üzere iki bölümden oluşur. Bu iki kısım
genellikle ayrı dosyalara yerleştirilir, arayüz dosyası .h ad uzantısını kullanır
ve .m ad uzantısını kullanan uygulama . Arayüz girdiğinde
ayrı bir dosya, uygulama dosyası aşağıdakilerle başlar:
#import " interface_file.h "
Örnek değişkenleri, aşağıdakileri izleyen ayraçla ayrılmış bir blokta bildirilir:
arayüz bölümünün başlığı. Objective-C, sınıf değişkenlerini desteklemiyor
direkt olarak. Ancak, uygulamada tanımlanan statik bir global değişken
file bir sınıf değişkeni olarak kullanılabilir.
Bir sınıfın uygulama bölümü, yöntemlerin tanımlarını içerir.
ilgili arayüz bölümünde bildirilir.
Objective-C, sınıfların iç içe geçmesine izin vermez.
12.6.2 Kalıtım
Objective-C yalnızca tek devralmayı destekler. Her sınıfın bir ebeveyni olmalıdır
NSObject adlı önceden tanımlanmış kök sınıf dışında . sahip olmak için bir neden
tek kök sınıf, evrensel olarak ihtiyaç duyulan bazı işlemlerin olmasıdır.
Bunlar arasında alloc ve init sınıf yöntemleri vardır . Yeni bir ebeveyn sınıfı
sınıf, arabirim yönergesinde, ekli iki nokta üst üste işaretinden sonra bildirilir.
aşağıdaki gibi tanımlanan sınıfın adı:
@interface myNewClass: NSObject {
Temel sınıf veri üyeleri özel olarak bildirilebildiğinden, alt sınıflar
mutlaka alt türler değildir. Tabii ki, korunan ve kamuya açık tüm veriler

Sayfa 571
550
Bölüm 12 Nesne Yönelimli Programlama Desteği
üst sınıfın üyeleri alt sınıf tarafından miras alınır. Yeni yöntemler
ve örnek değişkenler alt sınıfa eklenebilir. Tüm yöntemleri hatırlayın
halka açıktır ve bu değiştirilemez. Altta tanımlanan bir yöntem
sınıf ve aynı ada, aynı dönüş türüne ve aynı sayı ve türe sahip
of parametresi, devralınan yöntemi geçersiz kılar. Geçersiz kılınan yöntem olabilir
alt sınıfın başka bir yönteminde super aracılığıyla çağrılır , par-
ent nesne. Kalıtsal bir yöntemin geçersiz kılınmasını engellemenin bir yolu yoktur.
Smalltalk'ta olduğu gibi, Objective-C'de herhangi bir yöntem adı herhangi bir yerde çağrılabilir.
nesne. Çalışma zamanı sistemi, nesnenin böyle bir yöntemi olmadığını keşfederse
(uygun protokolle), bir hata oluşur.
Objective-C, C++'ın özel ve korumalı türevlerini desteklemez.
Nesne yönelimli programlamayı destekleyen diğer dillerde olduğu gibi,
bir alt sınıfın örneğinin yapıcısı her zaman sınıfın yapıcısını çağırmalıdır.
başka bir şey yapmadan önce ebeveyn sınıfı. Üst sınıfın adı uygunsa
structor init , bu aşağıdaki ifadeyle yapılır:
[ süper başlangıç];
Objective-C, alt sınıflamanın yanı sıra bir sınıfı genişletmenin iki yolunu içerir:
kategoriler ve protokoller. Bir sınıfa metot koleksiyonu eklenebilir.
kategori adı verilen bir yapı . Kategori, bir sınıfın ikincil arabirimidir.
yöntemlerin bildirimlerini içerir. Yeni örnek değişkenleri dahil edilemez
ikincil arayüz. Böyle bir arayüzün sözdizimsel formu örneklenmiştir.
aşağıdakiler tarafından:
#"Stack.h"yi içe aktar
@interface Yığını (StackExtend)
-( int ) ikinciFromTop;
-( boşluk ) dolu;
@son
Bu kategorinin adı StackExtend'dir . Orijinal arayüz erişilebilir
içe aktarıldığından, ana sınıfın belirtilmesine gerek yoktur. Yeni
yöntemler, orijinal arayüzün yöntemleriyle karıştırılır. Sonuç olarak,
kategorilere bazen karışımlar denir . Karışımlar bazen eklemek için kullanılır
farklı sınıflara belirli işlevler. Ve elbette, sınıfın hala bir
üyelerini miras aldığı normal üst sınıf. Yani, karışımlar bazılarını sağlar
olabilecek adlandırma çakışmaları olmadan çoklu kalıtımın faydaları
modüller, işlevlerinde modül adları gerektirmediyse oluşur. Tabii ki,
bir kategorinin ayrıca adını içeren bir uygulama bölümü olmalıdır.
uygulamada sınıf adından sonra parantez içindeki kategorinin
yönergesi aşağıdaki gibidir:
@implementation Yığını (StackExtend)
Uygulamanın kategorideki tüm yöntemleri uygulaması gerekmez.

Sayfa 572
12.6 Objective-C 551'de Nesne Yönelimli Programlama Desteği
Çoklu kalıtımın bazı faydalarını sağlamanın başka bir yolu daha vardır.
Objective-C'deki tance, protokoller. Objective-C sağlamasa da
soyut sınıflar, C++'da olduğu gibi, protokoller bunlarla ilgilidir. Bir protokol bir listedir
yöntem bildirimleri. Bir protokolün sözdizimi aşağıdakilerle örneklenmiştir:
@protokol MatrixOps
-(Matris *) ekleyin: (Matris *) mat;
-(Matris *) çıkarma: (Matris *) mat;
@isteğe bağlı
-(Matris *) çarpma: (Matris *) mat;
@son
Bu örnekte, MatrixOps , protokolün adıdır. eklenti ve
çıkarma yöntemleri, protokolü kullanan bir sınıf tarafından uygulanmalıdır.
Bu kullanıma, protokolün uygulanması veya benimsenmesi denir . İsteğe bağlı kısım
çarpma yönteminin bir sistem tarafından uygulanabileceğini veya uygulanamayacağını belirtir.
benimseyen sınıf.
Bir protokolü benimseyen bir sınıf, protokolün adını köşeli parantez içinde listeler.
arabirim yönergesinde sınıfın adından sonra, aşağıdaki gibi:
@interface Sınıfım: NSObject <Protocol>
12.6.3 Dinamik Bağlama
Objective-C'de polimorfizm,
diğer yaygın programlama dillerinin çoğunda yapılır. bir polimorfik
değişken, id türünde olduğu bildirilerek oluşturulur . Böyle bir değişken referans verebilir
herhangi bir nesne. Çalışma zamanı sistemi, hangi nesnenin sınıfını takip eder?
bir kimlik türü değişkeni başvurur. Böyle bir değişken aracılığıyla bir yönteme çağrı yapılırsa,
mümkünse, birinin var olduğu varsayılarak, çağrı dinamik olarak doğru yönteme bağlıdır.
Örneğin, bir programın Circle adında tanımlanmış sınıfları olduğunu varsayalım.
ve Kare ve her ikisinin de draw adlı yöntemleri vardır . Aşağıdakileri göz önünde bulundur
iskelet kodu:
// nesneleri oluştur
Daire *myCircle = [[Daire tahsisi] init];
Kare *mySquare = [[Square alloc] init];
// Nesneleri başlat
[myCircle setCircumference: 5];
[mySquare setSide: 5];
// id değişkenini oluştur
id şekliRef;
// Kimliği daireye referans verecek şekilde ayarlayın ve çizin

Sayfa 573
552
Bölüm 12 Nesne Yönelimli Programlama Desteği
shapteRef = myCircle;
[şekilRef çizimi];
// Kimliği kareye referans verecek şekilde ayarlayın
şekilRef = mySquare;
[şekilRef çizimi];
Bu kod ilk ikisi ile daire ve sonra kare, çizer beraberlik yöntemlerine
ShapeRef nesne başvurusu aracılığıyla çağrılır .
12.6.4 Değerlendirme
Objective-C'de nesne yönelimli programlama desteği yeterlidir,
ufak tefek eksiklikler olsa da. Aşırı önlemenin bir yolu yok-
kalıtsal bir yöntemin sürmesi. Kimlik verileriyle polimorfizm desteği
type overkill'dir, çünkü değişkenlerin herhangi bir nesneye başvurmasına izin verir,
bir miras hattında olanlar. Birden fazla için doğrudan destek olmamasına rağmen
kalıtım, dil sağlayan bir mixin, kategoriler biçimi içerir
tüm dezavantajları olmaksızın çoklu kalıtımın bazı yetenekleri.
Kategoriler, herhangi bir sınıfa bir dizi davranış eklenmesine izin verir. protokoller
sağlayan Java'dakiler gibi arabirimlerin yeteneklerini sağlar.
çoklu kalıtımın bazı yetenekleri.
12.7 Java'da Nesne Yönelimli Programlama Desteği
Java'nın sınıf, kalıtım ve metot tasarımı, Java'nınkine benzer.
C++, bu bölümde yalnızca Java'nın C++'dan farklı olduğu alanlara odaklanacağız.
12.7.1 Genel Özellikler
C++'da olduğu gibi Java, hem nesneleri hem de nesne olmayan verileri destekler. Ancak Java'da,
yalnızca ilkel skaler türlerin değerleri (Boolean, karakter ve sayısal
türleri) nesneler değildir. Java'nın numaralandırmaları ve dizileri nesnelerdir. Sebep
nesne olmayanlara sahip olmak verimliliktir.
Java 5.0+ sürümünde, ilkel değerler girdiklerinde örtük olarak zorlanır
nesne bağlamı. Bu zorlama, ilkel değeri nesnenin bir nesnesine dönüştürür.
ilkel değerin türünün sarmalayıcı sınıfı. Örneğin, bir int değeri koymak
veya nesne bağlamındaki değişken, bir Tamsayı nesnesinin oluşturulmasına neden olur.
int ilkel değeri . Bu zorlamaya boks denir .
C++ sınıfları ebeveyni olmayacak şekilde tanımlanabilirken, bu mümkün değildir.
Java'da. Tüm Java sınıfları, kök sınıfın, Object veya bazılarının alt sınıfları olmalıdır.
Object öğesinin soyundan gelen sınıf .
Tüm Java nesneleri açık yığın dinamiktir. Çoğu yeni ile tahsis edilir
operatörü, ancak açık bir ayırma operatörü yoktur. Çöp toplama

Sayfa 574
12.7 Java 553'te Nesne Yönelimli Programlama Desteği
depolama ıslahı için kullanılır. Diğer birçok dil özelliği gibi, ancak
çöp toplama, sarkan işaretçiler gibi bazı ciddi sorunları önler.
başka sorunlara neden olabilir. Böyle bir zorluk ortaya çıkar çünkü çöp top-
lector, bir nesne tarafından işgal edilen depolama alanını yeniden tahsis eder veya geri alır, ancak
daha fazla. Örneğin, bir nesnenin yığın dışında bir kaynağa erişimi varsa
Bir dosya veya paylaşılan bir kaynaktaki kilit gibi bellek, çöp toplayıcı
bunları geri almayın. Bu durumlar için Java, özel bir
Bir C++ yıkıcı işleviyle ilgili olan , finalize yöntemi .
Çöp toplayıcı yaklaşık olduğunda bir finalize yöntemi örtük olarak çağrılır.
nesne tarafından işgal edilen depolama alanını geri almak için. Sonlandırma ile ilgili sorun şudur:
çalışacağı zamanın zorlanamaz, hatta tahmin bile edilemez. alternatif
çöp olmak üzere bir nesne tarafından tutulan kaynakları geri almak için finalize kullanma
Toplanan, ıslahı yapan bir yöntemi içermesidir. Tek sorun
bununla, nesnelerin tüm istemcilerinin bu yöntemin farkında olması ve
aramayı unutmayın.
12.7.2 Kalıtım
Java'da, bir yöntem final olarak tanımlanabilir , bu, bunun olamayacağı anlamına gelir.
herhangi bir alt sınıfta geçersiz kılınır. Ne zaman nihai amaçlı sözcük belirtildi
bir sınıf tanımında, sınıfın alt sınıflanamayacağı anlamına gelir. Ayrıca şu anlama gelir
yöntem çağrılarının alt sınıfın yöntemlerine bağlantıları statik olarak bağlıdır.
Java ek açıklama içerir @ Geçersiz kıl derleyici bildirir,
aşağıdaki yöntemin bir yöntemi geçersiz kılıp kılmadığını belirlemek için kontrol edin.
ata sınıfı. Olmazsa, derleyici bir hata mesajı verir.
C++ gibi, Java da üst sınıf oluşturucunun komuttan önce çağrılmasını gerektirir.
alt sınıf yapıcısı çağrılır. Parametreler ebeveyne geçirilecekse
sınıf yapıcısı, bu yapıcı aşağıdaki gibi açıkça çağrılmalıdır.
örnek:
süper (100, doğru );
Üst sınıf kurucuya açık bir çağrı yoksa, derleyici ekler
üst sınıftaki sıfır parametreli oluşturucuya bir çağrı.
Java, C++'ın özel ve korumalı türevlerini desteklemez. Bir
Java tasarımcılarının alt sınıfların alt tipler olması gerektiğine inandıklarını tahmin edebilir,
özel ve korumalı türevler desteklendiğinde bunlar değildir. Böylece,
onları dahil etmediler. Java'nın ilk sürümleri bir koleksiyon içeriyordu, Vector ,
bir koleksiyon içeriğindeki verileri işlemek için uzun bir yöntem listesi içeriyordu.
yapı. Java Bu modeller ayrıca bir alt sınıfı dahil Vector , Yığın , hangi
push ve pop işlemleri için eklenen yöntemler. Ne yazık ki, çünkü Java
Özel türetilmesi vardır değil, bütün metodları Vector görünür de yer aldı
Stack yapılan sınıf, Stack operasyonların çeşitli buna yükümlü nesneleri
bu nesneleri geçersiz kılabilir.
Java doğrudan yalnızca tek bir devralmayı destekler. Ancak, bir tür içerir
birden çok öğe için kısmi destek sağlayan arabirim adı verilen soyut sınıfın

Sayfa 575
554
Bölüm 12 Nesne Yönelimli Programlama Desteği
miras. 8 Bir arabirim tanımı, bir sınıf tanımına benzer, ancak bunun dışında
yalnızca adlandırılmış sabitleri ve yöntem bildirimlerini içerebilir (tanımları değil).
Yapıcılar veya soyut olmayan yöntemler içeremez. Yani, bir arayüz hayır
adının gösterdiğinden daha fazlası—yalnızca bir sınıfın belirtimini tanımlar.
(Bir C++ soyut sınıfının örnek değişkenlere sahip olabileceğini ve bunlardan biri hariç tümünün
yöntemler tamamen tanımlanabilir.) Bir sınıf, bir arabirimi devralmaz;
onu uygular. Aslında, bir sınıf herhangi bir sayıda arabirim uygulayabilir. İle
bir arabirim uygularsa, sınıf, sahip olduğu tüm yöntemleri uygulamalıdır.
özellikler (ancak gövdeler değil) arabirim tanımında görünür.
Çoklu kalıtımı simüle etmek için bir arayüz kullanılabilir. Bir sınıf olabilir
bir sınıftan türetilebilir ve arayüz tak-
ikinci bir ebeveyn sınıfının yerini alıyor. Buna bazen mixin kalıtsal denir.
tance, çünkü arayüzün sabitleri ve yöntemleri,
üst sınıftan devralınan yöntemler ve verilerin yanı sıra herhangi bir yeni veri ve/veya
alt sınıfta tanımlanan yöntemler.
Arayüzlerin bir başka ilginç özelliği, başka bir arayüz sağlamalarıdır.
bir tür polimorfizm. Bunun nedeni, arayüzlerin tür olarak ele alınabilmesidir. İçin
örneğin, bir yöntem, bir arabirim olan resmi bir parametre belirtebilir. böyle bir
biçimsel parametre, uygulayan herhangi bir sınıfın gerçek bir parametresini kabul edebilir.
arabirim, yöntemi polimorfik hale getirir.
Parametre olmayan bir değişken de bir inter- tipinde bildirilebilir.
yüz. Böyle bir değişken, aşağıdakileri uygulayan herhangi bir sınıfın herhangi bir nesnesine başvurabilir.
arayüz.
Çoklu kalıtımla ilgili sorunlardan biri, bir sınıf olduğunda ortaya çıkar.
iki ana sınıftan türetilmiştir ve her ikisi de aynı
isim ve protokol. Arayüzler ile bu sorun önlenir. Her ne kadar bir sınıf
bir arabirim uygulayan, tüm yöntemler için tanımlar sağlamalıdır.
arabirimde belirtilen, sınıf ve arabirimin her ikisi de yöntemleri içeriyorsa
aynı ad ve protokolle sınıfın bu yöntemi yeniden uygulamasına gerek yoktur.
Bu nedenle, çoklu kalıtım ile oluşabilecek yöntem adı çakışmaları,
tek kalıtım ve arabirimler ile oluşmaz. Ayrıca, değişken adı
arayüzler değişkenleri tanımlayamadığı için çatışmalardan tamamen kaçınılır.
Bir arabirim, çoklu kalıtımın yerine geçmez, çünkü çoklu
tiple kalıtım, kodun yeniden kullanımı vardır, arabirimler ise kodun yeniden kullanılmasını sağlamaz.
Bu önemli bir farktır, çünkü kodun yeniden kullanımı birincil faydalardan biridir.
mirasın faydaları. Java, bu eksikliği kısmen önlemenin bir yolunu sunar. Bir
Uygulanan arabirimlerin çoğu, soyut bir sınıfla değiştirilebilir.
devralınabilecek kodu içerebilir, böylece bazı kodların yeniden kullanımı sağlanabilir.
Arayüzlerin çoklu kalıtımın yerini almasıyla ilgili bir sorun
şudur: Bir sınıf iki arabirimi uygulamaya çalışırsa ve her ikisi de tanımlar
aynı ada ve protokole sahip yöntemler, uygulamanın bir yolu yoktur.
hem de sınıfta.
Bir arabirim örneği olarak, standın sıralama yöntemini düşünün.
dar Java sınıfı, Array . Bu yöntemi kullanan herhangi bir sınıf, bir
8. Bir Java arabirimi, Objective-C'deki bir protokole benzer.

Sayfa 576
12.7 Java 555'te Nesne Yönelimli Programlama Desteği
sıralanacak öğeleri karşılaştırmak için bir yöntemin uygulanması. bu
jenerik Karşılaştırılabilir arabirim, bu karşılaştırma için protokolü sağlar
CompareTo adlı yöntem . Karşılaştırılabilir inter- için kod
yüzü şöyle:
genel arayüz Karşılaştırılabilir <T> {
public int karşılaştırma To(T b);
}
CompareTo yöntemi nesnesi durumunda negatif tamsayı dönmelidir
çağrıldığı parametre nesnesinden önce aittir, varsa sıfır
eşittir ve parametre nesneden önce aitse pozitif bir tamsayı
hangi CompareTo çağrıldı. Karşılaştırılabilirler arasını uygulayan bir sınıf
face, genel türdeki herhangi bir nesne dizisinin içeriğini sıralayabilir.
uygulanan compareTo jenerik türü için yöntem uygulanır ve
uygun değeri sağlar.
Arayüzlere ek olarak Java, aşağıdakilere benzer soyut sınıfları da destekler.
C++ olanlar. Bir Java soyut sınıfının soyut yöntemleri şu şekilde temsil edilir:
yalnızca soyut ayrılmış sözcüğü içeren yöntemin başlığı . bu
soyut sınıf da soyut olarak işaretlenir . Tabii ki, soyut sınıflar olamaz
örneklendi.
Bölüm 14, Java olay işlemede arabirimlerin kullanımını gösterir.
12.7.3 Dinamik Bağlama
C++'da dinamik bağlamaya izin vermek için bir yöntem sanal olarak tanımlanmalıdır. Java'da,
çağrılan yöntem olmadığı sürece tüm yöntem çağrıları dinamik olarak bağlanır
final olarak tanımlanır , bu durumda geçersiz kılınamaz ve tüm bağlamalar
statik. Statik bağlama, yöntemin statik veya özel olması durumunda da kullanılır .
hangi geçersiz kılmaya izin vermez.
12.7.4 İç İçe Sınıflar
Java'da iç içe geçmiş sınıfların birkaç çeşidi vardır ve bunların tümü aşağıdaki avantajlara sahiptir:
yuvalama sınıfı hariç, paketlerindeki tüm sınıflardan gizlenir. Olmayan-
doğrudan başka bir sınıfa yerleştirilmiş statik sınıflara iç sınıflar denir .
Bir iç sınıfın her örneğinin, örneğe yönelik örtük bir işaretçisi olmalıdır
ait olduğu yuvalama sınıfının. Bu, iç içe geçmiş yöntemleri verir
özel dahil olmak üzere yuvalama sınıfının tüm üyelerine sınıf erişimi
üyeler. Statik iç içe sınıflar bu işaretçiye sahip değildir, bu nedenle erişemezler
yuvalama sınıfının üyeleri. Bu nedenle, Java'daki statik iç içe sınıflar gibidir
C++'ın iç içe sınıfları.
Statik kapsamlı bir dilde garip görünse de,
iç sınıfa, özel üyelere bile dış sınıftan erişilebilir. Çok
referanslar, iç sınıf nesnesine başvuran değişkeni içermelidir. İçin

Sayfa 577
556
Bölüm 12 Nesne Yönelimli Programlama Desteği
örneğin, dış sınıfın iç sınıfın bir örneğini oluşturduğunu varsayalım.
aşağıdaki ifade:
myInner = bu . yeni İç();
Ardından, iç sınıf sum adında bir değişken tanımlıyorsa , buna başvurulabilir.
myInner.sum olarak dış sınıf .
Yuvalanmış bir sınıfın bir örneği, yalnızca yuvalama örneğinin içinde var olabilir
sınıf. İç içe sınıflar da anonim olabilir. Anonim iç içe sınıflar
karmaşık sözdizimi, ancak gerçekten bir sınıfı tanımlamanın yalnızca kısaltılmış bir yoludur.
sadece bir yerden kullanılır. Anonim iç içe sınıf örneği görünür
14. Bölümde.
Bir yerel iç içe sınıfı da iç içe geçme sınıfının bir yöntem tanımlanmıştır. Yerel
iç içe sınıflar hiçbir zaman bir erişim belirteci ( private veya public ) ile tanımlanmaz .
Kapsamları her zaman yuvalama sınıflarıyla sınırlıdır. Yerel iç içe geçmiş bir yöntem
sınıf, yuvalama sınıfında tanımlanan değişkenlere ve son değişkenlere erişebilir
yerel iç içe sınıfın tanımlandığı yöntemde tanımlanır. Üyeler
yerel bir iç içe sınıfın yalnızca yerel iç içe geçmiş sınıfın
sınıf tanımlanır.
12.7.5 Değerlendirme
Java'nın nesne yönelimli programlamayı destekleme tasarımı, Java'nınkine benzer.
C++, ancak nesne yönelimli ilkelere daha tutarlı bağlılık kullanır.
Java ebeveynsiz sınıflara izin vermez ve "normal" olarak dinamik bağlama kullanır
yöntem çağrılarını yöntem tanımlarına bağlamanın yolu. Bu elbette artar
yürütme süresi, birçok yöntem bağlamasının olduğu dillerin biraz üzerinde
statik. Ancak bu tasarım kararının verildiği sırada çoğu Java programı
yorumlandı, bu nedenle yorumlama süresi ekstra bağlama süresini önemsiz hale getirdi.
olamaz. Bir sınıf tanımının içeriği için erişim kontrolü, aşağıdaki durumlarda oldukça basittir:
türetme arasında değişen C++ erişim kontrolleri ormanıyla karşılaştırıldığında
arkadaş işlevleri için kontroller. Son olarak, Java bir tür sağlamak için arayüzleri kullanır.
tüm dezavantajlarına sahip olmayan çoklu kalıtım desteği
gerçek çoklu kalıtım.
12.8 C#'da Nesne Yönelimli Programlama Desteği
C#'ın nesne yönelimli programlama desteği, Java'nınkine benzer.
12.8.1 Genel Özellikler
C#, Java'nınkine çok benzeyen sınıflarla hem sınıfları hem de yapıları içerir.
sınıflar ve yapılar biraz daha az güçlü yığın dinamik yapılardır.
Önemli bir fark, yapıların değer türleri olmasıdır; yani, onlar yığın

Sayfa 578
12.8 C# 557'de Nesne Yönelimli Programlama Desteği
dinamik. Bu, nesne dilimleme sorununa neden olabilir, ancak bu önlenir
yapıların alt sınıflanamayacağı kısıtlamasıyla. Nasıl C# ile ilgili daha fazla ayrıntı
Yapılar, sınıflarından farklıdır, Bölüm 11'de görülmektedir.
12.8.2 Kalıtım
C#, sınıfları tanımlamak için C++ sözdizimini kullanır. Örneğin,
public class NewClass : ParentClass { . . . }
Üst sınıftan devralınan bir yöntem, türetilmiş sınıfta değiştirilebilir.
alt sınıfta tanımını new ile işaretleyerek sınıf . Yeni yöntem, deri
normal erişime üst sınıfta aynı adı taşıyan yöntem. Ancak,
üst sınıf sürümü, çağrının önüne base ile eklenerek hala çağrılabilir . İçin
örnek,
temel .Draw();
C#'ın arabirim desteği, Java'nınkiyle aynıdır.
12.8.3 Dinamik Bağlama
Yöntem çağrılarının C#'daki yöntemlere dinamik olarak bağlanmasına izin vermek için, hem temel
yöntem ve türetilmiş sınıflardaki karşılık gelen yöntemler özel olarak
işaretlenmiş. Temel sınıf yöntemi , C++'da olduğu gibi virtual ile işaretlenmelidir . İle
aynı ada sahip bir alt sınıftaki bir yöntemin amacını netleştirin ve
Bir ata sınıfında sanal bir yöntem olarak protokol, C# bu tür yöntemleri gerektirir
üst sınıf sanal yöntemini geçersiz kılacaklarsa geçersiz kılma olarak işaretlenirler . 9
Örneğin, Bölüm'de görünen C++ Shape sınıfının C# sürümü
12.5.3 aşağıdaki gibidir:
public class Şekil {
genel sanal boşluk Draw() { . . . }
. . .
}
public class Çember : Şekil {
public geçersiz kılma void Draw() { . . . }
. . .
}
public class Dikdörtgen : Şekil {
public geçersiz kılma void Draw() { . . . }
. . .
}
public class Kare : Dikdörtgen {
9. Bunun Java'da @Override ek açıklamasıyla belirtilebileceğini hatırlayın.

Sayfa 579
558
Bölüm 12 Nesne Yönelimli Programlama Desteği
public geçersiz kılma void Draw() { . . . }
. . .
}
C#, C++'ınkine benzer soyut yöntemler içerir, ancak bunlar
farklı sözdizimi ile belirtilir. Örneğin, aşağıdaki bir C# özetidir
yöntem:
soyut genel boşluk Draw();
En az bir soyut yöntem içeren bir sınıf, soyut bir sınıftır ve
Her soyut sınıf işaretlenmesi gerekir soyut . Soyut sınıflar olamaz
örneklendi. Soyut bir sınıfın herhangi bir alt sınıfının anlık olacağı sonucu çıkar.
ated, devraldığı tüm soyut yöntemleri uygulamalıdır.
Java'da olduğu gibi, tüm C# sınıfları nihayetinde tek bir kökten türetilir.
sınıf, Nesne . Nesne sınıfı dahil yöntemlerden bir koleksiyon tanımlar
Tüm C# türleri tarafından devralınan ToString , Finalize ve Equals .
12.8.4 İç İçe Sınıflar
Doğrudan bir sınıfa yerleştirilmiş AC# sınıfı, Java statik iç içe sınıf gibi davranır
(C++'da iç içe geçmiş bir sınıf gibidir). C++ gibi, C# da yuvalamayı desteklemez.
Java'nın statik olmayan iç içe sınıfları gibi davranan sınıflar.
12.8.5 Değerlendirme
C#, en son tasarlanmış C tabanlı nesne yönelimli dil olduğundan,
tasarımcılarının öncekilerden öğrenmesi ve
geçmişin başarılarını çoğalttı ve bazı sorunları çözdü. Bir
Java ile ilgili birkaç sorunla birleştiğinde bunun sonucu, farklılıkların olmasıdır.
C#'ın nesne yönelimli programlama desteği ile Java'nınki arasında
Nispeten küçük. Java'nın sahip olmadığı C# yapılarının kullanılabilirliği,
bir gelişme sayılabilir. Java'daki gibi, C#'ın nesne desteği
yönelimli programlama, çoğu kişinin bir
Gelişme.
12.9 Ada 95'te Nesne Yönelimli Programlama Desteği
Ada 95, bazı önemli uzantılarla Ada 83'ten türetilmiştir. Bu bölüm
nesneleri desteklemek için tasarlanmış uzantılara kısa bir bakış sunar.
odaklı programlama Çünkü Ada 83 zaten bina yapıları içeriyordu.
soyut veri türleri, Ada 95 için gerekli ek özellikler şunlardı:
kalıtımı ve dinamik bağlamayı destekler. Ada 95'in tasarım hedefleri
Ada 83'ün tip ve paket yapılarında minimal değişiklikler içerecekti.
ve mümkün olduğu kadar çok statik tip kontrolünü koruyun. Nesne yönelimli olduğunu unutmayın

Sayfa 580
12.9 Ada 95 559'da Nesne Yönelimli Programlama Desteği
Ada 95'te programlama karmaşıktır ve bu bölüm yalnızca bir
kısa ve eksik açıklaması.
12.9.1 Genel Özellikler
Ada 95 sınıflar denilen türde yeni bir kategorisidir etiketli tipleri olabilir
ya kayıtlar ya da özel türler. izin veren paketlerde tanımlanırlar.
ayrı ayrı derlenecektir. Etiketli türler bu şekilde adlandırılır çünkü her nesne
etiketli bir tür, örtük olarak, onun durumunu belirten sistem tarafından sürdürülen bir etiket içerir.
tip. Etiketli bir türdeki işlemleri tanımlayan alt programlar görünür
tür bildirimi ile aynı bildirim listesinde. Aşağıdakileri göz önünde bulundur
örnek:
ile Ada.Strings.Unbounded; Ada.Strings.Unbounded kullanın ;
paket Person_Pkg olduğunu
type Kişi özel olarak etiketlendi ;
Prosedür Ekran (P: in Kişi);
özel
tip Kişi etiketlendi
kayıt
Ad : Sınırsız_Dize;
Adres : Sınırsız_Dize;
Yaş : Tamsayı;
bitiş kaydı;
son Person_Pkg;
Bu tip paket tanımlayan bir kişi başına yararlıdır ve aynı zamanda mümkün
türetilmiş sınıfların ana sınıfı olarak hizmet eder.
C++'dan farklı olarak, yapıcı veya yıkıcı alt öğelerinin örtük olarak çağrılması yoktur.
Ada 95'teki programlar. Bu alt programlar yazılabilir, ancak
programcı tarafından açıkça çağrılır.
12.9.2 Kalıtım
Ada 83, türetilmiş türleri ile yalnızca dar bir kalıtım biçimini destekler ve
alt tipler. Bunların her ikisinde de, var olan bir temele dayalı olarak yeni bir tür tanımlanabilir.
tür. İzin verilen tek değişiklik, değer aralığını kısıtlamaktır.
yeni tip. Bu, nesne yönelimli için gereken tam kalıtım türü değildir.
Ada 95 tarafından desteklenen programlama.
Ada 95'teki türetilmiş türler, etiketli türlere dayanmaktadır. Yeni varlıklar eklendi
bir kayıt tanımına yerleştirerek devralınan varlıklara. Yi hesaba kat
aşağıdaki örnek:
ile Person_Pkg; Person_Pkg kullanın ;
Student_Pkg paketi :
type Student is yeni Kişi ile

Sayfa 581
560
Bölüm 12 Nesne Yönelimli Programlama Desteği
kayıt
Grade_Point_Average : Kayan;
Grade_Level : Tamsayı;
kayıt sonu ;
Prosedür Ekran (St: in Öğrenci);
son Student_Pkg;
Bu örnekte, türetilmiş Student türü , kendi öğelerine sahip olacak şekilde tanımlanmıştır.
ana sınıf, Person , yeni varlıklar Grade_Point_Average ile birlikte
ve Grade_Level . Ayrıca Display prosedürünü yeniden tanımlar . Bu yeni sınıf
gerektirmeden değiştirilebilmesi için ayrı bir pakette tanımlanmıştır.
üst türün tanımını içeren paketin yeniden derlenmesi.
Bu kalıtım mekanizması, birinin varlıklarını engellemesine izin vermez.
ebeveyn sınıfın türetilmiş sınıfa dahil edilmesi. Sonuç olarak, türetilmiş
sınıflar yalnızca üst sınıfları genişletebilir ve bu nedenle alt türlerdir. Ancak,
Aşağıda kısaca tartışılan alt kitaplık paketleri tanımlamak için kullanılabilir.
alt tür olmayan alt sınıflar.
Aşağıdaki tanımlara sahip olduğumuzu varsayalım:
P1 : Kişi;
S1 : Öğrenci;
Fred : Kişi := (To_Unbounded_String("Fred"),
To_Unbounded_String("321 Dut
Şerit"), 35);
Freddie : Öğrenci :=
(To_Unbounded_String("Freddie"),
To_Unbounded_String("725 Main St."),
20, 3.25, 3);
Çünkü Öğrenci bir alt türü olan Kişi , atama
P1 := Freddie;
yasal olmalı ve öyle. Grade_Point_Average ve Grade_Level
Freddie'nin varlıkları , gerekli zorlamada basitçe göz ardı edilir. Bu
nesne dilimlemenin başka bir örneği.
Şimdi açık olan soru, ters yönde bir atama olup olmadığıdır.
yasaldır; yani, bir Öğrenciye bir Kişi atayabilir miyiz ? Ada 95'te bu
eylem, alt sınıftaki varlıkları içeren bir biçimde yasaldır. Örneğimizde,
aşağıdakiler yasaldır:
Ö1 := (Fred, 3.05, 2);
Ada 95, çoklu kalıtım sağlamaz. Her ne kadar genel sınıflar
ve çoklu kalıtım sadece uzaktan ilişkili kavramlardır, bunun bir yolu var
jenerik kullanarak çoklu kalıtıma benzer bir etki elde edin. Ancak öyle
C++ yaklaşımı kadar zarif değil ve burada tartışılmıyor.

Sayfa 582
12.9 Ada 95 561'de Nesne Yönelimli Programlama Desteği
12.9.3 Dinamik Bağlama
Ada 95, prosedür çağrılarının hem statik bağlanmasını hem de dinamik bağlanmasını sağlar.
etiketli türlerde prosedür tanımları. Dinamik bağlama, bir
bir sınıf hiyerarşisindeki tüm türleri temsil eden sınıf çapında tür
özel tip. Her etiketli türün örtük olarak sınıf çapında bir türü vardır. etiketli için
type T , sınıf çapındaki tip T' class ile belirtilir . Eğer T Etiketli tip bir değişkenlik olduğu
tipi güçlü T' sınıf tipi bir nesnenin saklanması için T ya da türetilen herhangi bir tür T .
Bölüm 12.9.2'de tanımlanan Kişi ve Öğrenci sınıflarını tekrar düşünün .
Diyelim ki, Person' sınıfı türünde bir değişkenimiz var , Pcw , bazen
bir Person nesnesine başvurur ve bazen bir Student nesnesine başvurur.
Ayrıca, tarafından başvurulan nesneyi görüntülemek istediğinizi varsayalım PCW , gözönüne alındığında
Bir Person nesnesine mi yoksa bir Öğrenci nesnesine mi atıfta bulunduğundan daha az . Bu
sonuç, Display çağrısının dinamik olarak doğruya bağlanmasını gerektirir.
Ekran sürümü . Kişi türünü alan yeni bir prosedür kullanabiliriz.
parametresini görüntüler ve Display'e gönderir . Aşağıdaki böyle bir prosedürdür:
prosedür Display_Any_Person (P: içinde Kişiler) olduğu
başlamak
Ekran(P);
son Display_Any_Person;
Bu prosedür, aşağıdaki aramaların her ikisi ile de çağrılabilir:
ile Person_Pkg; Person_Pkg kullanın ;
ile Student_Pkg; Student_Pkg kullanın ;
P : Kişi;
S : Öğrenci;
Pcw : Kişi sınıfı ;
. . .
Pcw := P;
Display_Any_Person(Pcw); -- Ekranı Şahsen arayın
Pcw := S;
Display_Any_Person(Pcw); -- Öğrenci'deki Ekranı çağırın
Ada 95+ ayrıca polimorfik işaretçileri de destekler. sahip olacakları şekilde tanımlanmıştır.
sınıf çapında tip, olduğu gibi
type Any_Person_Ptr , erişim Person' sınıfıdır ;
Ada 95+'da tamamen soyut temel türler aşağıdakiler dahil edilerek tanımlanabilir:
tip tanımlarında ve alt program tanımlarında ayrılmış kelime özeti
tion. Ayrıca, alt program tanımlarının gövdeleri olamaz. Düşünmek
bu örnek:
paket Base_Pkg (şimdiki değeri)
T türü soyut etiketli boş kayıttır ;

Sayfa 583
562
Bölüm 12 Nesne Yönelimli Programlama Desteği
prosedür Do_It (A : T) soyuttur ;
son Base_Pkg;
12.9.4 Çocuk Paketleri
Paketler doğrudan diğer paketlerin içine yerleştirilebilir, bu durumda paketler olarak adlandırılırlar.
çocuk paketleri . Bu tasarımla ilgili olası bir sorun, bir paketin
önemli sayıda alt paket ve bunlar büyük, iç içe geçme paketi
etkili bir derleme birimi olamayacak kadar büyük olur. Çözüm nispeten
basit: Alt paketlerin fiziksel olarak ayrı birimler (dosyalar) olmasına izin verilir.
ayrı olarak derlenebilirler, bu durumda alt kitaplık paketleri olarak adlandırılırlar .
Bir alt paket, ayrılmış Word'den önce özel olarak bildirilir.
ayrılmış kelime ile paket private . Özel bir kişinin mantıksal konumu
alt paket, şartname paketindeki bildirimlerin başındadır.
yuvalama paketinin yaşı. Özel çocuk paketinin bildirimleri şunlardır:
iç içe yerleştirme paketi bir
Çocuğun adını içeren madde ile.
Bir çocuk paketinin önemli bir özelliği, özel paketin bile
ebeveyninin parçaları ona görünür. Alt paketler bir alternatif sağlar
ana varlıkların bu görünürlüğü nedeniyle sınıf türetme. Yani, özel
ebeveyn paketinin parçaları, bir ebeveyn sınıfındaki korumalı üyeler gibidir;
bir sınıfı genişletmek için bir alt paket kullanılır.
Alt kitaplık paketleri herhangi bir zamanda bir programa eklenebilir. Onlar yapmıyor
üst paketin veya üst paketin istemcilerinin yeniden derlenmesini gerektirir.
C++'da arkadaş tanımları yerine alt kitaplık paketleri kullanılabilir.
Örneğin, üyelere erişebilecek bir alt program yazılması gerekiyorsa,
iki farklı sınıf, ana paket sınıflardan birini tanımlayabilir ve
alt paket diğerini tanımlayabilir. Ardından, alt paketteki bir alt program
her ikisinin de üyelerine erişebilir. Ayrıca, bir arkadaşa ihtiyaç duyulursa C++'da
bir sınıf tanımlandığında bilinmiyor, değiştirilmesi ve yeniden derlenmesi gerekecek
Böyle bir ihtiyaç keşfedildiğinde. Ada 95+'da yeni alt paketlerdeki yeni sınıflar
ana paketi bozmadan tanımlanabilir, çünkü her isim
üst pakette tanımlanan, alt pakette görünür.
12.9.5 Değerlendirme
Ada, nesne yönelimli programlama için tam destek sunar, ancak kullanıcılar
diğer nesne yönelimli dillerden bazıları, bu desteğin hem zayıf olduğunu görebilir
ve biraz karmaşık. Paketler soyut veriler oluşturmak için kullanılabilse de
türleri, aslında daha genelleştirilmiş kapsülleme yapılarıdır. çocuk olmadıkça
kütüphane paketleri kullanılıyorsa, kalıtımı kısıtlamanın bir yolu yoktur, bu durumda
tüm alt sınıflar alt türlerdir. Bu erişim kısıtlaması biçimi, iletişimde sınırlıdır.
C++, Java ve C# tarafından sunulanlara benzer.
C++ açıkça Ada 95'ten daha iyi bir çoklu kalıtım biçimi sunar.
Ancak, alt kitaplık birimlerinin varlıklarına erişimi kontrol etmek için kullanılması

Sayfa 584
12.10 Ruby 563'te Nesne Yönelimli Programlama Desteği
ebeveyn sınıfı, arkadaş işlevlerinden daha temiz bir çözüm gibi görünüyor ve
C++ sınıfları.
Başlatma için C++'a yapıcıların ve yıkıcıların dahil edilmesi
nesneler iyidir, ancak Ada 95 böyle yetenekler içermez.
Bu iki dil arasındaki diğer bir fark, tasarımcının bir
C++ kök sınıfı, belirli bir üye işlevinin statistik olup olmayacağına karar vermelidir.
cally veya dinamik olarak bağlı. Seçim statik bağlama lehine yapılırsa, ancak
sistemdeki sonraki bir değişiklik dinamik bağlama gerektirir, kök sınıf
değişti. Ada 95'te bu tasarım kararının tasarımı ile verilmesine gerek yoktur.
kök sınıf. Her çağrı, statik mi yoksa dinamik mi olacağını kendisi belirleyebilir.
kök sınıfın tasarımından bağımsız olarak caly bağlı.
12.10 Ruby'de Nesne Yönelimli Programlama Desteği
Daha önce belirtildiği gibi, Ruby tamamen nesne yönelimli bir programlama dilidir.
Smalltalk duygusu. Dildeki hemen hemen her şey bir nesnedir ve hepsi birer nesnedir.
Hesaplama, mesaj geçişi yoluyla gerçekleştirilir. programlar olmasına rağmen
infix operatörlerini kullanan ve bu nedenle aynı görünüme sahip ifadeler
Java gibi dillerdeki ifadeler, bu ifadeler aslında
ileti geçişi. Smalltalk'ta olduğu gibi, a + b yazıldığında, exe-
a tarafından başvurulan nesneye + iletisini göndererek, bir başvuruyu ileterek kesilir.
parametre olarak b nesnesine . Başka bir deyişle, a + b , a.+ b olarak uygulanır .
12.10.1 Genel Özellikler
Ruby sınıfı tanımları, C++ ve Java gibi dillerin tanımlarından farklıdır.
yürütülebilir olmaları açısından. Bu nedenle, açık kalmalarına izin verilir.
yürütme sırasında. Bir program, bir sınıfa herhangi bir sayıda üye ekleyebilir,
sadece yeni sınıfı içeren sınıfın ikincil tanımlarını sağlayarak
üyeler. Yürütme sırasında, bir sınıfın mevcut tanımı,
yürütülen sınıfın tüm tanımları. Yöntem tanımları
bir programın iki versiyonu arasında seçim yapmasına izin veren yürütülebilir bir dosyadır.
yürütme sırasında yöntem tanımı, sadece iki tanımı koyarak
bir seçim yapısının then and else yan tümcesi.
Ruby'deki tüm değişkenler nesnelere referanstır ve tümü tipsizdir. Hatırlamak
Ruby'deki tüm örnek değişkenlerin adlarının bir at işareti ( @ ) ile başladığını .
Diğer yaygın programlama dillerinden açık bir şekilde ayrılarak,
Ruby'deki erişim denetimi, veriler için yöntemlerden farklıdır. Tüm örnek
verilerin varsayılan olarak özel erişimi vardır ve bu değiştirilemez. Eğer harici erişim
bir örnek değişkenine ihtiyaç duyulursa, erişimci yöntemleri tanımlanmalıdır. İçin
örneğin, aşağıdaki iskelet sınıfı tanımını göz önünde bulundurun:
sınıf MyClass
# Bir kurucu

Sayfa 585
564
Bölüm 12 Nesne Yönelimli Programlama Desteği
def başlat
@bir = 1
@iki = 2
son
# @one için bir alıcı
kesin bir
@bir
son
# @one için bir ayarlayıcı
def one=(my_one)
@one = benim_birim
son
sınıfın sonu MyClass
Setter yönteminin adına eklenen eşittir (=) işareti,
değişken atanabilir. Bu nedenle, tüm setter yöntemlerinin kendilerine iliştirilmiş eşit işaretleri vardır.
isimler. Bir alıcı yönteminin gövdesi , Ruby tasarımını gösterir.
olmadığında değerlendirilen son ifadenin değerini döndüren yöntemler
iade beyanı. Bu durumda @one değeri döndürülür.
Getter ve setter yöntemlerine çok sık ihtiyaç duyulduğu için Ruby,
her ikisi için de kısayollar. Biri bir sınıfın ikisi için alıcı yöntemlerine sahip olmasını istiyorsa
örnek değişkenler, @one ve @two , bu alıcılar şu şekilde belirtilebilir:
sınıfta tek ifade:
attr_reader :bir, :iki
attr_reader aslında :one ve : two'yu gerçek olarak kullanan bir işlev çağrısıdır.
parametreler. Bir değişkenden iki nokta üst üste ( : ) ile önce gelmek, değişken adının
atıfta bulunduğu nesneye atıfta bulunmak yerine kullanılabilir.
Benzer şekilde ayarlayıcı oluşturan işleve attr_writer adı verilir . Bu
işlev, attr_reader ile aynı parametre profiline sahiptir .
Getter ve setter metotları yaratma fonksiyonları böyle adlandırılmıştır çünkü
sınıfın nesneleri için protokol sağlarlar ve bunlara daha sonra attri-
butes . Bu nedenle, bir sınıfın öznitelikleri veri arayüzünü tanımlar (veri
erişimci yöntemleri aracılığıyla genel) sınıfın nesnelerine.
Ruby nesneleri, örtük olarak bir kurucu çağıran new ile oluşturulur .
Ruby sınıfındaki olağan kurucu, initialize olarak adlandırılır . Bir kurucu
bir alt sınıf, ana sınıfın ayarlayıcıları olan veri üyelerini başlatabilir
tanımlı. Bu, gerçek parametre olarak başlangıç ​​değerleriyle süper çağrılarak yapılır.
eter. super ile aynı ada sahip üst sınıftaki yöntemi çağırır.
super çağrısının göründüğü yöntem .

Sayfa 586
12.10 Ruby 565'te Nesne Yönelimli Programlama Desteği
Adlarından önce iki ile belirtilen sınıf değişkenleri
işaretleri ( @@ ), sınıfa ve örneklerine özeldir. Bu gizlilik olamaz
değişti. Ayrıca, global ve örnek değişkenlerin aksine, sınıf değişkenleri
kullanılmadan önce başlatılır.
12.10.2 Kalıtım
Ruby'de alt sınıflar, simge yerine küçüktür ( < ) kullanılarak tanımlanır.
C++ kolonu. Örneğin,
sınıf MySubClass < TemelSınıf
Ruby'nin yöntem erişim kontrolleriyle ilgili belirgin bir şey, onların
sadece erişim kontrol fonksiyonları çağrılarak bir alt sınıfta değiştirilebilir.
Bu, bir temel sınıfın iki alt sınıfının tanımlanabileceği anlamına gelir.
alt sınıflardan biri, temel sınıfta tanımlanan bir yönteme erişebilir, ancak nesneler
diğer alt sınıftan olamaz. Ayrıca, bu, bir kişinin erişimini değiştirmesine izin verir.
temel sınıftaki genel olarak erişilebilir yönteme, özel olarak erişilebilir bir yönteme
alt sınıf. Böyle bir alt sınıf açıkça bir alt tip olamaz.
Ruby modülleri, genellikle tanımlamak için kullanılan bir adlandırma kapsüllemesi sağlar.
fonksiyon kütüphaneleri. Bununla birlikte, modüllerin belki de en ilginç yönü,
işlevlerine doğrudan sınıflardan erişilebilmesidir. Modüle erişim
bir sınıfta, aşağıdaki gibi bir include ifadesi ile belirtilir :
Matematik dahil
Bir modül dahil etmenin etkisi, sınıfın aşağıdakilere bir işaretçi kazanmasıdır.
modül ve modülde tanımlanan işlevleri etkin bir şekilde devralır. Aslında,
bir sınıfa bir modül dahil edildiğinde, modül bir proxy üst sınıfı olur
sınıfın. Böyle bir modül bir karışımdır.
12.10.3 Dinamik Bağlama
Ruby'de dinamik bağlama desteği Smalltalk'takiyle aynıdır. Değişkenler
yazılmamış; daha ziyade, hepsi herhangi bir sınıfın nesnelerine referanslardır. Yani, tüm değişken-
yetenekler polimorfiktir ve yöntemlere yapılan tüm yöntem çağrıları dinamiktir.
12.10.4 Değerlendirme
Ruby, en saf anlamıyla nesne yönelimli bir programlama dili olduğu için,
nesne yönelimli programlama için desteği açıkça yeterlidir. Ancak,
sınıf üyelerine erişim denetimi, C++'ınkinden daha zayıftır. Ruby değil
mixins ile yakından ilgili olmasına rağmen, soyut sınıfları veya arayüzleri destekler
arayüzler. Son olarak, büyük ölçüde Ruby yorumlandığından, yürütme verimliliği
ciency, derlenmiş dillerden çok daha kötüdür.

Sayfa 587
566
Bölüm 12 Nesne Yönelimli Programlama Desteği
12.11 Nesneye Yönelik Yapıların Uygulanması
Nesne yönelimli programlama için dil desteğinin en az iki bölümü vardır
dil uygulayıcıları için ilginç sorular ortaya çıkaran: depolama yapıları
örneğin değişkenler ve mesajların yöntemlere dinamik bağlantıları. Bunda
bölümünde bunlara kısaca göz atacağız.
12.11.1 Örnek Veri Depolama
C++'da sınıflar, C'nin kayıt yapılarının uzantıları olarak tanımlanır—yapılar.
Bu benzerlik, sınıfın örnek değişkenleri için bir depolama yapısı önerir.
örnekler - bir kaydın örneği. Bu yapının bu formuna sınıf örneği denir
kayıt (CIR) . Bir CIR'nin yapısı statiktir, bu nedenle derleme zamanında oluşturulur ve
sınıf örneklerinin verilerinin oluşturulması için bir şablon olarak kullanılır. Her sınıfın kendi
kendi CIR. Bir türetme gerçekleştiğinde, alt sınıf için CIR, bunun bir kopyasıdır.
sonunda eklenen yeni örnek değişkenleri için girişlerle üst sınıfın.
CIR'nin yapısı statik olduğundan, tüm örnek değişkenlerine erişim
CIR'nin başlangıcından itibaren sabit ofsetler kullanılarak kayıtlarda olduğu gibi yapılabilir
misal. Bu, bu erişimleri kayıt alanları için olanlar kadar verimli kılar.
12.11.2 Yöntem Çağrılarının Yöntemlere Dinamik Bağlanması
Statik olarak bağlı bir sınıftaki yöntemlerin, aşağıdakiler için CIR'de yer alması gerekmez.
sınıf. Ancak dinamik olarak bağlanacak yöntemlerin girişleri olmalıdır.
bu yapıda. Bu tür girişler, yalnızca kodun bir göstergesine sahip olabilir.
nesne oluşturma zamanında ayarlanması gereken yöntem. Bir yönteme yapılan çağrılar daha sonra
CIR'deki bu işaretçi aracılığıyla ilgili koda bağlanın. bu
bu tekniğin dezavantajı, her örneğin işaretçileri depolaması gerekmesidir.
örnekten çağrılabilecek tüm dinamik olarak bağlı yöntemlere.
Çağrılabilecek dinamik olarak bağlı yöntemlerin listesinin
bir sınıfın örneği, o sınıfın tüm örnekleri için aynıdır. bu yüzden
bu tür yöntemlerin listesi yalnızca bir kez saklanmalıdır. Yani bir örnek için CIR
çağrılan yöntemleri bulmasını sağlamak için bu listeye yalnızca tek bir işaretçiye ihtiyaç duyar. bu
liste için depolama yapısına genellikle sanal yöntem tablosu (vtable) denir .
Yöntem çağrıları, vtable'ın başlangıcından itibaren ofsetler olarak temsil edilebilir.
Bir ata sınıfının polimorfik değişkenleri her zaman sınıfın CIR'sine başvurur.
doğru tür nesnesi, bu nedenle dinamik olarak bağlı bir nesnenin doğru sürümüne ulaşmak
yöntem garantilidir. Tüm yöntemlerin kullanıldığı aşağıdaki Java örneğini düşünün.
dinamik olarak bağlıdır:
genel sınıf A {
genel int a, b;
public void draw() { . . . }
genel int alanı() { . . . }
}

Sayfa 588
12.11 Nesneye Yönelik Yapıların Uygulanması 567
public class B , A'yı genişletir {
genel int c, d;
public void draw() { . . . }
genel geçersiz eleme() { . . . }
}
İçin CIR'lar A ve B sınıfları, bunların vtables ile birlikte gösterilmektedir
Şekil 12.7. B'lerde alan yöntemi için yöntem işaretçisinin
vtable, A'nın alan yönteminin kodunu gösterir . Bunun nedeni, B'nin
A'nın alan yöntemini geçersiz kılmaz , bu nedenle B'nin bir müşterisi alanı çağırırsa , bu alandır
A'dan miras alınan yöntem. Öte yandan, çizim için işaretçiler ve
B'nin vtable'ında eleme yapın ve B'nin çekilişine gelin ve eleyin . Beraberlik yöntemi kullanılarak aşırı
B'de basılmış ve elek , B'de bir ekleme olarak tanımlanır.
Çoklu kalıtım, dinamik bağlamanın uygulanmasını zorlaştırır.
Aşağıdaki üç C++ sınıf tanımını göz önünde bulundurun:
A sınıfı {
kamu :
int a;
sanal boşluk eğlencesi() { . . . }
sanal boşluk init() { . . . }
};
B sınıfı {
Şekil 12.7
Tek mirasa sahip CIR'lere bir örnek
B
a
vtable işaretçisi
A alanı için kod
A için vtable
sınıf örneği
A için kayıt
A'nın çekilişi için kod
B
a
D
C
vtable işaretçisi
B çekilişi için kod
B için tablo
sınıf örneği
B için kayıt
B'nin elemesi için kod
A alanı için kod

Sayfa 589
568
Bölüm 12 Nesne Yönelimli Programlama Desteği
kamu :
int b;
sanal boşluk toplamı() { . . . }
};
C sınıfı : genel A, genel B {
kamu :
int c;
sanal boşluk eğlencesi() { . . . }
sanal boşluk dud() { . . . }
};
Cı- sınıfı değişken devralır a ve init gelen bir yöntem bir sınıfı. o
yeniden tanımlayan eğlenceli , yöntem her ne kadar onun hem eğlenceli ve ebeveyn sınıfın o
A , bir polimorfik değişken ( A tipinde ) aracılığıyla potansiyel olarak görülebilir . Gönderen B ,
C , b değişkenini ve toplam yöntemini devralır . C kendi değişkenini tanımlar, c ,
ve kalıtsal olmayan bir yöntemi tanımlar dud . C için bir CIR , A'nın verilerini içermelidir ,
B'nin verileri ve C'nin verilerinin yanı sıra tüm görünür yöntemlere erişmenin bazı yolları.
Tek kalıtım altında, CIR,
tüm görünür yöntemlerin kodunun adresleri. Çoklu kalıtım ile,
Ancak, o kadar basit değil. En az iki farklı görüş mevcut olmalıdır.
CIR'de mümkün—biri aşağıdakileri içeren ana sınıfların her biri için bir tane
alt sınıf için görünüm, C . Üst sınıftaki alt sınıfın görünümünün bu dahil edilmesi
sınıfın görüşü, tekli kalıtımın uygulanmasındaki gibidir.
Ayrıca iki tablo olmalıdır: biri A ve C görünümü için, diğeri B için
görüş. Bu durumda C için CIR'nin ilk kısmı , C ve A görünümü olabilir;
C ve A'dan miras alınan yöntemler için bir vtable işaretçisi ile başlar ,
ve A'dan devralınan verileri içerir . Bunu C'nin CIR'sinde takip eden B görünümüdür.
sanal yöntemleri için bir vtable işaretçi ile başlayan bölüm, B ise,
ardından B'den devralınan veriler ve C'de tanımlanan veriler gelir . için CIR
C , Şekil 12.8'de gösterilmiştir.
Şekil 12.8
Birden çok ebeveyni olan bir alt sınıf CIR örneği
vtable işaretçisi
a
C
B
C'nin vtable'ı (B kısmı)
vtable işaretçisi
(C ve A bölümü) için C'nin vtable'ı
sınıf örneği
C için kayıt
C'nin eğlencesi için kod
C'nin dud kodu
B'nin toplamı için kod
A'nın init'i için kod
C ve A'nın parçası
B'nin parçası
C'nin verileri

Sayfa 590
özet 569
ÖZET
Nesne yönelimli programlama üç temel kavram üzerine kuruludur: soyut
veri türleri, kalıtım ve dinamik bağlama. Nesne yönelimli programlama
diller paradigmayı sınıflar, yöntemler, nesneler ve mesajla destekler
geçen.
Bu bölümde nesne yönelimli programlama dillerinin tartışılması
Ter, yedi tasarım konusu etrafında döner: nesnelerin, alt sınıfların ve
alt tipler, tip kontrolü ve polimorfizm, tekli ve çoklu kalıtım,
dinamik bağlama, nesnelerin açık veya örtük olarak serbest bırakılması ve iç içe sınıflar.
Smalltalk saf nesne yönelimli bir dildir—her şey bir nesnedir ve
tüm hesaplama mesaj geçişi yoluyla gerçekleştirilir. Smalltalk'ta, tüm
alt sınıflar alt türlerdir. Tüm tip kontrolü ve mesajların metotlara bağlanması
dinamiktir ve tüm kalıtım tektir. Smalltalk'ın açık bir tahsisi yok
operasyon.
C++, veri soyutlama, kalıtım ve isteğe bağlı için destek sağlar
mesajların tüm geleneksel yöntemlerle birlikte yöntemlere dinamik olarak bağlanması
C'nin özellikleri. Bu, iki ayrı tip sistemine sahip olduğu anlamına gelir. C++ sağlar
çoklu kalıtım ve açık nesne ayırma. C++ çeşitli içerir
sınıflardaki varlıklar için erişim kontrolleri, bazıları alt sınıfların
alt tipler olmasıdır. Hem yapıcı hem de yıkıcı yöntemler dahil edilebilir.
sınıflar; her ikisi de dolaylı olarak adlandırılır.
Smalltalk'ın dinamik tip bağlaması biraz daha pro-
C++ hibrit dilden gramlama esnekliği, çok daha az verimlidir.
Objective-C, hem prosedürel hem de nesne yönelimli programlamayı destekler.
C++'dan daha az karmaşıktır ve daha az yaygın olarak kullanılır. Yalnızca tek bir kalıtım sağlanır.
ek yöntemlerin karıştırılmasına izin veren kategorilere sahip olmasına rağmen taşınır
bir sınıfa eklenebilir. Ayrıca Java'nınkine benzer protokollere sahiptir.
arayüzler. Bir sınıf herhangi bir sayıda protokolü benimseyebilir. Yapıcılar sahip olabilir
herhangi bir ad, ancak açıkça çağrılmaları gerekir. Polimorfizm ile desteklenir
önceden tanımlanmış tür, id . id türündeki bir değişken herhangi bir nesneye başvurabilir. Ne zaman
id türündeki bir değişken tarafından başvurulan bir nesne aracılığıyla bir yöntem çağrılır ;
bağlama dinamiktir.
C++'tan farklı olarak Java, karma bir dil değildir; sadece desteklemek içindir
nesne yönelimli programlama. Java'nın hem ilkel skaler türleri hem de sınıfları vardır.
Tüm nesneler öbekten ayrılır ve referans yoluyla erişilir.
değişkenler. Açık bir nesne ayırma işlemi yoktur—çöp toplama
kullanıldı. Yalnızca alt programlar yöntemlerdir ve yalnızca aracılığıyla çağrılabilirler.
nesneler veya sınıflar. Bir tür olmasına rağmen yalnızca tek kalıtım doğrudan desteklenir
arayüzler kullanılarak çoklu kalıtım mümkündür. Mesajların tüm bağlaması
to metotlar, aşırıya kaçamayan metotlar dışında dinamiktir.
basmış. Sınıflara ek olarak Java, ikinci bir kapsülleme olarak paketleri içerir.
inşa etmek.
Ada 95, etiketler aracılığıyla nesne yönelimli programlama için destek sağlar
kalıtımı destekleyebilen türler. Dinamik bağlama, sınıfla desteklenir-
geniş işaretçi türleri. Türetilmiş türler, üst türlerin uzantılarıdır.

Sayfa 591
570
Bölüm 12 Nesne Yönelimli Programlama Desteği
alt kitaplık paketlerinde tanımlanmıştır, bu durumda üst türün varlıkları
türetilmiş tipte elimine edilir. Alt kitaplık paketleri dışında, tüm alt sınıflar
alt türleridir.
C++ ve Java tabanlı olan C#, nesne yönelimli program-
ming. Nesneler, sınıflardan veya yapılardan başlatılabilir. yapı
nesneler yığın dinamiktir ve kalıtımı desteklemez. Türetilmiş bir yöntemde
sınıf, temel sınıfı dahil ederek üst sınıfın gizli yöntemlerini çağırabilir .
yöntem adı. Geçersiz kılınabilecek yöntemler virtual olarak işaretlenmelidir ve
ağır basan yöntemler ile işaretlenmiş olmalıdır geçersiz kılma . Tüm sınıflar (ve tüm
ilkeller) Object öğesinden türetilmiştir .
Ruby, tüm verilerin nesne olduğu nesne yönelimli bir betik dilidir.
Smalltalk'ta olduğu gibi, tüm nesneler yığın tahsislidir ve tüm değişkenler tipsizdir.
nesnelere referanslar. Tüm yapıcılar initialize olarak adlandırılır . Tüm örnek verileri
özeldir, ancak alıcı ve ayarlayıcı yöntemleri kolayca dahil edilebilir. Koleksiyon
erişim yöntemlerinin sağlandığı tüm örnek değişkenlerin
sınıfa genel arayüz. Bu tür örnek verilere nitelikler denir. Ruby sınıfları
yürütülebilir olmaları ve herhangi bir zamanda değiştirilebilir olmaları açısından dinamiktirler.
zaman. Ruby yalnızca tekli kalıtımı destekler ve alt sınıflar zorunlu değildir
alt tipler.
Bir sınıfın örnek değişkenleri, yapısı bir CIR'de saklanır.
statiktir. Alt sınıfların kendi CIR'leri ve üst sınıflarının CIR'leri vardır.
sınıf. Dinamik bağlama, depolayan sanal bir yöntem tablosuyla desteklenir.
belirli yöntemlere işaret eder. Çoklu kalıtım, işi büyük ölçüde karmaşıklaştırır.
CIR'lerin ve sanal yöntem tablolarının uygulanması.
İNCELEME SORULARI
1. Nesne yönelimli dillerin üç karakteristik özelliğini tanımlayın.
2. Bir sınıf değişkeni ile bir örnek değişken arasındaki fark nedir?
3. Çoklu kalıtım nedir?
4. Polimorfik değişken nedir?
5. Geçersiz kılma yöntemi nedir?
6. Dinamik bağlamanın, kendisine göre büyük bir avantaj olduğu bir durumu tanımlayın.
yokluk.
7. Sanal yöntem nedir?
8. Soyut yöntem nedir? Soyut sınıf nedir?
9. Nesne için bu bölümde kullanılan sekiz tasarım konusunu kısaca açıklayın.
yönelik diller.
10. Yuvalama sınıfı nedir?
11. Bir nesnenin mesaj protokolü nedir?
12. Smalltalk nesneleri nereden tahsis edilir?

Sayfa 592
Soruları gözden geçir 571
13. Smalltalk mesajlarının yöntemlere nasıl bağlı olduğunu açıklayın. Bunu ne zaman yapar
yer almak?
14. Smalltalk'ta ne tür kontrol yapılır? Ne zaman gerçekleşir?
15. Smalltalk, tekli veya çoklu ne tür kalıtımı destekler?
16. Smalltalk'ın en önemli iki etkisi nelerdir?
bilgi işlem?
17. Özünde, tüm Smalltalk değişkenleri tek tiptir. O tip nedir?
18. C++ nesneleri nereden tahsis edilebilir?
19. C++ yığınla ayrılmış nesneler nasıl serbest bırakılır?
20. Tüm C++ alt sınıfları alt türleri midir? Eğer öyleyse, açıklayın. Değilse, neden olmasın?
21. Bir C++ yöntemi çağrısı hangi koşullar altında statik olarak bir
yöntem?
22. Tasarımcıların hangi yöntemleri belirlemesine izin vermenin sakıncası var?
statik olarak bağlanabilir mi?
23. C++'da özel ve genel türevler arasındaki farklar nelerdir?
24. C++' da arkadaş işlevi nedir ?
25. C++'da saf sanal işlev nedir?
26. C++'da bir üst sınıfın yapıcısına parametreler nasıl gönderilir?
27. Smalltalk arasındaki en önemli pratik fark nedir?
ve C++?
28. Objective-C yöntemi hiçbir şey döndürmezse, hangi dönüş türü belirtilir?
başlığında mı?
29. Objective-C çoklu kalıtımı destekliyor mu?
30. Objective-C sınıfı, başlığında bir üst sınıf belirtemez mi?
31. Objective-C'deki kök sınıf nedir?
32. Objective-C'de bir yöntem geçersiz kılınamayacağını nasıl gösterebilir?
alt sınıflarda?
33. Objective-C kategorisinin amacı nedir?
34. Objective-C protokolünün amacı nedir?
35. Objective-C'de id türünün birincil kullanımı nedir ?
36. Java'nın tür sistemi C++'dan nasıl farklıdır?
37. Java nesneleri nereden tahsis edilebilir?
38. Boks nedir?
39. Java nesneleri nasıl serbest bırakılır?
40. Tüm Java alt sınıfları alt türleri midir?
41. Java'da üst sınıf kurucuları nasıl çağrılır?
42. Bir Java yöntemi çağrısı hangi koşullar altında statik olarak bir
yöntem?

Sayfa 593
572
Bölüm 12 Nesne Yönelimli Programlama Desteği
43. C#'daki geçersiz kılma yöntemleri, sözdizimsel olarak diğerlerinden ne şekilde farklıdır?
C++'daki muadilleri?
44. Devralınan bir yöntemin üst sürümü, geçersiz kılınan nasıl olabilir?
C#'da bu alt sınıfta bir alt sınıf çağrılabilir mi?
45. Tüm Ada 95 alt sınıfları alt türleri midir?
46. ​​Ada 95'teki bir alt programa yapılan çağrı nasıl dinamik olarak belirtilir?
bir alt program tanımına bağlı mı? Bu karar ne zaman verilir?
47. Ruby, tamsayı ve tamsayı için olanlar gibi ilkel türleri nasıl uygular?
kayan nokta verileri?
48. Bir Ruby sınıfında getter metotları nasıl tanımlanır?
49. Ruby, örnek değişkenler için hangi erişim kontrollerini destekler?
50. Ruby, yöntemler için hangi erişim kontrollerini destekliyor?
51. Tüm Ruby alt sınıfları alt türleri midir?
52. Ruby çoklu kalıtımı destekliyor mu?
PROBLEM SETİ
1. Nesne yönelimli programlama desteğinin önemli kısmı nedir?
SIMULA 67'de eksik mi?
2. Aralarındaki ilişki için hangi yollarla “uyumlu” tanımlanabilir?
geçersiz kılınan bir yöntem ve geçersiz kılınan yöntem?
3. C++ ve Java'nın dinamik bağlamasını karşılaştırın.
4. C++ ve Java'nın sınıf varlık erişim denetimlerini karşılaştırın.
5. C++ ve Ada 95'in sınıf varlık erişim kontrollerini karşılaştırın.
6. C++'ın çoklu kalıtımını inter- tarafından sağlananla karşılaştırın.
Java'da yüzler.
7. Birden çok kalıtımın olduğu bir programlama durumu nedir?
arayüzlere göre önemli bir avantaj mı?
8. İyileştirilmiş soyut veri türleriyle ilgili iki sorunu açıklayın
miras yoluyla.
9. Bir alt sınıfın üst sınıfında yapabileceği değişiklik kategorilerini tanımlayın
sınıf.
10. Kalıtımın bir dezavantajını açıklayın.
11. Tüm değerlere sahip olmanın avantaj ve dezavantajlarını açıklayın.
dil nesneler olsun.
12. Bir alt sınıf için bir is-a ilişkisine sahip olmak tam olarak ne anlama gelir?
onun ebeveyn sınıfı?
13. Bir geçersiz kılmanın parametrelerinin ne kadar yakın olduğu konusunu açıklayın.
yöntem, geçersiz kıldığı yönteminkilerle eşleşmelidir.

Sayfa 594
Programlama Alıştırmaları 573
14. Smalltalk'ta tip kontrolünü açıklayın.
15. Java tasarımcıları, açıkçası, ek ücrete değmeyeceğini düşündüler.
olduğu gibi, herhangi bir yöntemin statik olarak bağlanmasına izin verme verimliliği
C++ ile. Java tasarımının lehine ve aleyhine olan argümanlar nelerdir?
16. Tüm Java nesnelerinin ortak bir
Ata?
17. Java'daki finalize yan tümcesinin amacı nedir ?
18. Java yığın dinamik nesnelere izin verirse ne elde edilir?
yığın dinamik nesneler? İkisine birden sahip olmanın dezavantajı ne olurdu?
19. Ada 95'in polimorfizm sağlama şeklini C++ ile karşılaştırın.
programlama kolaylığı açısından.
20. C++ soyut sınıfı ile Java arasındaki farklar nelerdir?
arayüz?
21. C++'daki polimorfizm desteğini aşağıdakilerle karşılaştırın.
Amaç-C.
22. Objective-C protokollerinin yeteneklerini ve kullanımını Java'nınkilerle karşılaştırın.
arayüzler.
23. Objective-C tasarımcılarının kullanma kararını eleştirel olarak değerlendirin.
Smalltalk'ın geleneksel sözdizimi yerine yöntem çağrıları için sözdizimi
nesne yönelimli destekleyen çoğu zorunlu tabanlı dil tarafından kullanılır
programlama.
24. Bir sınıfın neden Java'da birden çok arabirim uygulamasına izin verdiğini ve
C#, C++'da çoklu kalıtımla aynı sorunları yaratmaz
yaratır.
25. C#'ın neden Java'nın statik olmayanını içermediği konusunu inceleyin ve açıklayın.
iç içe sınıflar.
26. Soyut bir sınıf için bir referans değişken tanımlayabilir misiniz? ne işe yarar
böyle bir değişken olur mu?
27. Java ve Ruby'deki örnek değişkenler için erişim kontrollerini karşılaştırın.
28. Java'daki örnek değişkenler için tür hatası algılamasını karşılaştırın ve
Yakut.
PROGRAMLAMAALIŞTIRMALAR
1. single_linked_list , stack_2 ve tail_2 sınıflarını yeniden yazın
Java'da Bölüm 12.5.2'de ve sonucu aşağıdaki C++ sürümüyle karşılaştırın.
okunabilirlik ve programlama kolaylığı açısından.
2. Programlama Alıştırma 1'i Ada 95'i kullanarak tekrarlayın.
3. Programlama Alıştırma 1'i Ruby kullanarak tekrarlayın.
4. Programlama Alıştırma 1'i Objective-C'yi kullanarak tekrarlayın.

Sayfa 595
574
Bölüm 12 Nesne Yönelimli Programlama Desteği
5. Temel sınıf A'yı tanımlayan bir C++ programı tasarlayın ve uygulayın.
kendisi de C alt sınıfına sahip olan bir B alt sınıfına sahiptir. A sınıfı şunları uygulamalıdır:
Hem B hem de C'de geçersiz kılınan bir yöntem belirtin.
A, B ve C'yi somutlaştıran ve üç çağrı içeren bir test sınıfı yazın.
yöntem. Çağrılardan biri statik olarak A'nın yöntemine bağlı olmalıdır. Bir
çağrı dinamik olarak B'nin yöntemine bağlı olmalı ve biri dinamik olmalıdır.
C'nin yöntemine kesin olarak bağlı. Tüm yöntem çağrıları bir
A sınıfına işaretçi.
6. Hem dinamik olarak bağlı bir yöntemi hem de C++'da çağıran bir program yazın.
statik olarak bağlı bir yöntem, çağrıları zamanlayarak çok sayıda
ikisi de. Zamanlama sonuçlarını karşılaştırın ve farkı hesaplayın
ikisinin gerektirdiği süre. Sonuçları açıklayın.
7. Programlama Alıştırma 5'i Java kullanarak, statik bağlamayı zorlayarak tekrarlayın.
nihai .

Sayfa 596
575
13.1 Giriş
13.2 Alt Program Düzeyinde Eşzamanlılığa Giriş
13.3 Semaforlar
13.4 Monitörler
13.5 Mesaj Geçişi
13.6 Eşzamanlılık için Ada Desteği
13.7 Java Konuları
13.8 C# Konuları
13.9 İşlevsel Dillerde Eşzamanlılık
13.10 İfade Düzeyinde Eşzamanlılık
13
eşzamanlılık

Sayfa 597
576
Bölüm 13 Eşzamanlılık
Bu bölüm, çeşitli eşzamanlılık türlerine girişlerle başlar.
alt program veya birim düzeyinde ve ifade düzeyinde. Dahil edilen kısa bir
en yaygın çok işlemcili bilgisayar mimarisi türlerinin tanımı
türler. Ardından, birim düzeyinde eşzamanlılık hakkında uzun bir tartışma sunulur. Bu başlar
önce anlaşılması gereken temel kavramların bir açıklaması ile
birim düzeyindeki mutabakat için dil desteğinin sorunlarını ve zorluklarını tartışmak
rency, özellikle rekabet ve işbirliği senkronizasyonu. Daha sonra, tasarım
eşzamanlılık için dil desteği sağlamaya yönelik sorunlar açıklanmıştır. Bunu takiben
uyum için dil desteğine yönelik üç ana yaklaşımın ayrıntılı bir tartışmasıdır.
rency: semaforlar, monitörler ve mesaj geçişi. Bir sözde kod örnek programı
semaforların nasıl kullanılabileceğini göstermek için kullanılır. Ada ve Java için kullanılır
monitörleri göstermek; mesaj geçişi için Ada kullanılır. destekleyen Ada özellikleri
eşzamanlılık biraz ayrıntılı olarak açıklanmıştır. Görevler odak noktası olmasına rağmen, korunan
(etkili bir şekilde izlenen) nesneler de tartışılmaktadır. Birim düzeyi için destek
Java ve C#'da iş parçacıkları kullanarak eşzamanlılık, yaklaşımlar da dahil olmak üzere tartışılır
senkronizasyon için. Bunu, eşzamanlılık desteğine ilişkin kısa genel bakışlar izler.
birkaç fonksiyonel programlama dili. Bölümün son kısmı kısa bir
bölümüne bir giriş de dahil olmak üzere ifade düzeyinde eşzamanlılık tartışması
High-Performance Fortran'da bunun için sağlanan dil desteği.
13.1 Giriş
Yazılım yürütmede eşzamanlılık dört farklı düzeyde gerçekleşebilir: talimat
seviye (aynı anda iki veya daha fazla makine talimatını yürütme), ifade
düzey (iki veya daha fazla üst düzey dil ifadesini aynı anda yürütme),
birim düzeyi (iki veya daha fazla alt program birimini aynı anda yürütme) ve pro-
gram seviyesi (aynı anda iki veya daha fazla program yürütme). Çünkü hiçbir lan-
Guage tasarım sorunları bunlarla ilgilidir, talimat düzeyinde ve program düzeyinde
eşzamanlılık bu bölümde ele alınmamıştır. Her iki altta da eşzamanlılık
program ve ifade seviyeleri tartışılır, çoğu odak
alt program seviyesi
İlk bakışta, eşzamanlılık basit bir kavram gibi görünebilir, ancak
programlama dili olan programcıya önemli zorluklar sunar
tasarımcı ve işletim sistemi tasarımcısı (çünkü desteğin çoğu
eşzamanlılık işletim sistemi tarafından sağlanır).
Eşzamanlı kontrol mekanizmaları programlama esnekliğini artırır. Onlar
işletimde karşılaşılan belirli problemler için kullanılmak üzere orijinal olarak icat edildi.
ancak çeşitli diğer programlama uygulamaları için gereklidirler.
tion. En yaygın olarak kullanılan programlardan biri artık Web tarayıcılarıdır.
tasarım büyük ölçüde eşzamanlılık üzerine kuruludur. Tarayıcılar birçok farklı işlem yapmalıdır.
ent aynı anda çalışır, aralarında veri gönderme ve alma
Web sunucuları, ekranda metin ve görüntü oluşturma ve kullanıcıya tepki verme
fare ve klavye ile eylemler. Bazı çağdaş tarayıcılar,
örnek Internet Explorer 9, birçok programın parçası olan ekstra çekirdekli işlemcileri kullanın.
bazı işlemlerini gerçekleştirmek için çağdaş kişisel bilgisayarlar,

Sayfa 598
13.1 Giriş 577
örneğin, istemci tarafı komut dosyası kodunun yorumlanması. Başka bir örnek
gerçek fiziksel sistemleri simüle etmek için tasarlanmış yazılım sistemleridir.
birden fazla eşzamanlı alt sistemden oluşur. Tüm bu tür uygulamalar için,
programlama dili (veya bir kitaplık veya en azından işletim sistemi)
birim düzeyinde eşzamanlılığı destekler.
İfade düzeyinde eşzamanlılık, birimdeki eşzamanlılıktan oldukça farklıdır
seviye. Bir dil tasarımcısının bakış açısından, ifade düzeyinde eşzamanlılık
büyük ölçüde, verilerin birden çok yere nasıl dağıtılması gerektiğini belirleme meselesidir.
bellekler ve hangi ifadelerin aynı anda yürütülebileceği.
Eşzamanlı yazılım geliştirmenin amacı, ölçeklenebilir ve
taşınabilir eşzamanlı algoritmalar Bir eşzamanlı algoritmasıdır ölçeklenebilir ise
daha fazla işlemci mevcut olduğunda yürütme hızı artar. Bu
önemli çünkü her yeni nesil işlemci sayısı artıyor.
makinelerin tanımı. Algoritmalar taşınabilir olmalıdır çünkü kullanım ömrü
donanım nispeten kısadır. Bu nedenle, yazılım sistemleri bağımlı olmamalıdır.
belirli bir mimaride - yani, makinelerde verimli bir şekilde çalışmalılar
farklı mimarilere sahip.
Bu bölümün amacı, eşzamanlılığın özelliklerini tartışmaktır.
kesin bir sonuç sunmaktan ziyade dil tasarımı sorunlarıyla en alakalı olanlardır.
eşzamanlılığın geliştirilmesi de dahil olmak üzere tüm eşzamanlılık konularının incelenmesi.
kiralama programları Bu, programlama üzerine bir kitap için açıkça uygunsuz olurdu.
Diller.
13.1.1 Çok İşlemcili Mimariler
Çok sayıda farklı bilgisayar mimarisinde birden fazla işlemci bulunur.
ve bir tür eşzamanlı yürütmeyi destekleyebilir. tartışmaya başlamadan önce
programların ve ifadelerin eşzamanlı yürütülmesi, kısaca bazılarını açıklıyoruz
bu mimariler.
Birden çok işlemciye sahip ilk bilgisayarların tek bir genel amacı vardı.
işlemci ve genellikle çevresel işlemciler olarak adlandırılan bir veya daha fazla işlemci,
sadece giriş ve çıkış işlemleri için kullanılan izin verilen bu mimari
1950'lerin sonlarında ortaya çıkan bu bilgisayarlar, bir programı yürütmek için
diğer programlar için aynı anda giriş veya çıkış gerçekleştirirken.
1960'ların başında, birden fazla tamamlanmış makineler vardı.
işlemciler Bu işlemciler, operatörün iş planlayıcısı tarafından kullanıldı.
toplu iş kuyruğundan ayrı işleri dağıtan sistem
ayrı işlemciler Program düzeyinde desteklenen bu yapıya sahip sistemler
eşzamanlılık
1960'ların ortalarında, birbirinin aynı olan birkaç kısmi özelliğe sahip makineler ortaya çıktı.
tek bir talimat akışından belirli talimatlarla beslenen alıcılar. İçin
örneğin, bazı makinelerde iki veya daha fazla kayan nokta çarpanı bulunurken,
diğerlerinin iki veya daha fazla tam kayan noktalı aritmetik birimi vardı. derleme
Bu makineler için, hangi talimatların kullanılabileceğini belirlemek için gerekliydi.
eşzamanlı olarak yürütülür ve bu talimatları buna göre programlanır. Sistemler
bu yapı ile komut düzeyinde eşzamanlılık desteklenir.

Sayfa 599
578
Bölüm 13 Eşzamanlılık
1966'da Michael J. Flynn bilgisayar mimarisinin bir sınıflandırmasını önerdi.
komut ve veri akışlarının tek mi yoksa çoklu mu olduğuna göre tanımlanır.
Bunların isimleri 1970'lerden 2000'lerin başına kadar yaygın olarak kullanıldı. İki
Birden çok veri akışı kullanan kategoriler aşağıdaki gibi tanımlanır:
aynı talimatı aynı anda yürüten birden fazla işlemciye sahip olmak, her biri
farklı veriler üzerinde, Tek Yönlü Çoklu Veri (SIMD) mimarisi olarak adlandırılır.
tabi bilgisayarlar. Bir SIMD bilgisayarında, her işlemcinin kendi yerel belleği vardır.
Bir işlemci, diğer işlemcilerin çalışmasını kontrol eder. Çünkü tüm
denetleyici dışındaki işlemciler aynı komutu aynı anda yürütürler,
yazılımda senkronizasyon gerekmez. Belki de en yaygın kullanılanı
SIMD makineleri, vektör işlemcileri adı verilen bir makine kategorisidir . Onlar
bir vektör işleminin işlenenlerini depolayan kayıt gruplarına sahiptir.
aynı komut tüm işlenenler grubu üzerinde aynı anda yürütülür.
Başlangıçta, bu mimariden en çok yararlanabilecek program türleri
genellikle hedef olan bir bilgi işlem alanı olan bilimsel hesaplamadaydı.
çok işlemcili makineler Ancak, SIMD işlemciler artık çeşitli amaçlar için kullanılmaktadır.
uygulama alanları arasında grafik ve video işleme. Yakın zamana kadar,
çoğu süper bilgisayar vektör işlemcileriydi.
Bağımsız olarak çalışan ancak birden çok işlemciye sahip bilgisayarlar
işlemleri senkronize edilebilen Çoklu Komutlu Çoklu- olarak adlandırılır.
Veri (MIMD) bilgisayarları. Bir MIMD bilgisayarındaki her işlemci,
kendi talimat akışı. MIMD bilgisayarları iki farklı durumda görünebilir.
şekiller: dağıtılmış ve paylaşılan bellek sistemleri. dağıtılmış MIMD
Her işlemcinin kendi belleğine sahip olduğu makineler ya yerleşik olabilir
tek bir şasi veya dağıtılmış, belki geniş bir alana. paylaşılan hafıza
MIMD makineleri açıkça bazı senkronizasyon araçları sağlamalıdır.
bellek erişim çakışmalarını önlemek. Dağıtılmış MIMD makineleri bile senkronizasyon gerektirir.
Tek programlarda birlikte çalışmak için kronizasyon. MIMD bilgisayarlar,
SIMD bilgisayarlardan daha geneldir, birim düzeyinde eşzamanlılığı destekler. bu
Bu bölümün ana odak noktası, paylaşılan bellek MIMD için dil tasarımıdır.
genellikle çok işlemcili olarak adlandırılan bilgisayarlar .
Güçlü ancak düşük maliyetli tek çipli bilgisayarların ortaya çıkmasıyla birlikte,
bu mikroişlemcilerin çok sayıda küçük işlemcilere bağlanması mümkündür.
ağlar tek bir kasa içinde. Genellikle kullanılan bu tür bilgisayarlar
kullanıma hazır mikroişlemciler, bir dizi farklı
üreticiler.
Yazılımın kullanmak için daha hızlı gelişmemesinin önemli bir nedeni
eşzamanlı makineler, işlemcilerin gücünün sürekli artmasıdır.
Eşzamanlı makineleri kullanmak için en güçlü motivasyonlardan biri,
hesaplama hızı. Bununla birlikte, iki donanım faktörü bir araya geldi.
mimaride herhangi bir değişiklik gerektirmeden daha hızlı hesaplama sağlar
yazılım sistemlerinden biridir. İlk olarak, işlemci saat hızları her biri ile daha hızlı hale geldi.
yeni nesil işlemciler (nesiller aşağı yukarı her 18
ay). İkincisi, birkaç farklı eşzamanlılık türü yerleşiktir.
işlemci mimarileri Bunlar arasında talimatların sıralanması ve
bellekten işlemciye veri (talimatlar alınır ve kodu çözülür)

Sayfa 600
13.1 Giriş 579
geçerli talimat yürütülürken), için ayrı satırların kullanılması
talimatlar ve veriler, talimatların ve verilerin önceden getirilmesi ve
aritmetik işlemlerin yürütülmesi. Bunların hepsi topluca gizli olarak adlandırılır.
eşzamanlılık . Yürütme hızındaki artışların sonucu,
yazılım geliştiricilerin üretmesini gerektirmeden büyük üretkenlik kazanımları oldu
Eşzamanlı yazılım sistemleri.
Ancak, durum artık değişiyor. İmza dizisinin sonu-
Bireysel işlemcilerin hızında önemli artışlar artık yakındır. Önemli
bilgi işlem gücündeki artışlar artık sayılardaki önemli artışlardan kaynaklanmaktadır.
işlemciler, örneğin Google tarafından çalıştırılanlar gibi büyük sunucu sistemleri ve
Amazon ve bilimsel araştırma uygulamaları. Diğer birçok büyük bilgi işlem görevleri
artık çok sayıda nispeten küçük işlemciye sahip makinelerde çalıştırılıyor.
Bilgi işlem donanımındaki bir diğer yeni gelişme, bilgisayarların geliştirilmesiydi.
Intel Core Duo ve Core gibi tek bir çip üzerinde birden fazla işlemci
Yazılım geliştiriciler üzerinde daha fazla baskı oluşturan dörtlü yongalar
mevcut çok işlemcili makinelerin daha fazla kullanımı. yapmazlarsa,
eşzamanlı donanım boşa harcanacak ve üretkenlik kazanımları önemli ölçüde
azaltmak.
13.1.2 Eşzamanlılık Kategorileri
Eşzamanlı ünite kontrolünün iki farklı kategorisi vardır. en doğal
eşzamanlılık kategorisi, birden fazla işlemin olduğu varsayıldığında,
sor kullanılabilir, aynı programdan birkaç program birimi tam anlamıyla yürütülür
eşzamanlı. Bu fiziksel eşzamanlılıktır . Bu kavramın hafif bir gevşemesi
eşzamanlılık, programcının ve uygulama yazılımının
gerçek eşzamanlılık sağlayan birden çok işlemci olduğu, aslında
programların fiili yürütmesi tek bir
işlemci. Bu mantıksal eşzamanlılıktır . Programcının ve dilinden
Tasarımcının bakış açısına göre mantıksal eşzamanlılık, fiziksel eşzamanlılık ile aynıdır.
Altta yatan dilin yeteneklerini kullanmak, dil uygulayıcısının görevidir.
işletim sistemi, mantıksal eşzamanlılığı ana bilgisayar donanımıyla eşleştirmek için. Her ikisi de
mantıksal ve fiziksel eşzamanlılık, eşzamanlılık kavramının şu şekilde kullanılmasına izin verir:
bir program tasarım metodolojisi. Bu bölümün geri kalanında, tartışma
hem fiziksel hem de mantıksal eşzamanlılık için geçerli olacaktır.
Bir program aracılığıyla yürütme akışını görselleştirmek için kullanışlı bir teknik
programın kaynak metninin ifadeleri üzerine yerleştirilmiş bir iş parçacığı hayal etmektir.
Belirli bir yürütmede ulaşılan her ifade, iş parçacığı temsili tarafından kapsanır.
bu infazı gönderiyor. Kaynak program aracılığıyla iş parçacığını görsel olarak takip etme
programın yürütülebilir sürümü aracılığıyla yürütme akışını izler. Nın-nin
Tabii ki, en basit programlar hariç hepsinde, iş parçacığı oldukça karmaşık bir
görsel olarak takip edilmesi imkansız olan yol. Resmi olarak, bir kontrol dizisi
bir programda, kontrol akarken ulaşılan program noktalarının sırasıdır.
program.
Eşyordamları olan (bkz. Bölüm 9) ancak eşzamanlı alt-programları olmayan programlar
programlar, bazen yarı-eşzamanlı olarak adlandırılsalar da, tek bir

Sayfa 601
580
Bölüm 13 Eşzamanlılık
kontrol ipi. Fiziksel eşzamanlılık ile yürütülen programlar,
çoklu kontrol konuları. Her işlemci iş parçacıklarından birini çalıştırabilir.
Mantıksal olarak eşzamanlı program yürütme aslında yalnızca bir
tek bir kontrol dizisi, bu tür programlar sadece tarafından tasarlanabilir ve analiz edilebilir.
onları birden fazla kontrol dizisine sahip olarak hayal etmek. tasarlanmış bir program
birden fazla kontrol iş parçacığına sahip olmanın çok iş parçacıklı olduğu söylenir . Ne zaman
çok iş parçacıklı bir program tek işlemcili bir makinede yürütülür, iş parçacıkları
tek bir iş parçacığına eşlenir. Bu senaryoda, sanal olarak
çok iş parçacıklı program.
İfade düzeyinde eşzamanlılık nispeten basit bir kavramdır. Ortak kullanımda
deyim düzeyinde eşzamanlılık, dizi üzerinde çalışan deyimleri içeren döngüler
öğeler çözülür, böylece işleme birden fazla pro-
mirasçılar. Örneğin, 500 tekrar çalıştıran ve bir ifade içeren bir döngü
500 dizi öğesinden birinde çalışan, 10 dizinin her biri için çözülebilir.
farklı işlemciler aynı anda 50 dizi öğesini işleyebilir.
13.1.3 Eşzamanlılık Kullanımı için Motivasyonlar
Eşzamanlı yazılım sistemleri tasarlamanın en az dört farklı nedeni vardır.
Birinci neden, çoklu programlara sahip makinelerde programların yürütülme hızıdır.
tip işlemciler Bu makineler, verimliliği artırmanın etkili bir yolunu sağlar.
yapmak üzere tasarlanmış olması koşuluyla, programların yürütme hızı
eşzamanlı donanım kullanımı. Şimdi çok sayıda yüklü
satılan kişisel bilgisayarların çoğu dahil olmak üzere çok işlemcili bilgisayarlar
son bir kaç yıl içinde. Bu donanım özelliğini kullanmamak israftır.
İkinci neden, bir makinede yalnızca bir işlemci olsa bile, bir
eşzamanlı yürütmeyi kullanmak için yazılan program, aynı programdan daha hızlı olabilir.
sıralı (eşzamanlı olmayan) yürütme için yazılmış gram. için gereklilik
Bunun olması, programın hesaplamaya bağlı olmamasıdır (sıralı sürüm
işlemciyi tam olarak kullanmaz).
Üçüncü neden, eşzamanlılığın farklı bir eşzamanlılık yöntemi sağlamasıdır.
problemlere program çözümlerini kavramsallaştırma. Birçok sorunlu alan ödünç verir
özyineleme ile aynı şekilde doğal olarak eşzamanlılığa
bazı sorunlara çözümler tasarlamanın doğal bir yolu. Ayrıca, birçok program
fiziksel varlıkları ve faaliyetleri simüle etmek için yazılmıştır. Birçok durumda, sistem
simüle edilmek birden fazla varlık içerir ve varlıklar ne yaparsa yapsın
aynı anda yaparlar - örneğin kontrollü bir hava sahasında uçan uçaklar,
bir iletişim ağındaki röle istasyonları ve bir ağdaki çeşitli makineler
fabrika. Bu tür sistemleri simüle etmek için eşzamanlılık kullanan yazılımlar kullanılmalıdır.
doğru.
Eşzamanlılık kullanmanın dördüncü nedeni, aşağıdakileri yapabilen uygulamaları programlamaktır.
yerel olarak veya İnternet aracılığıyla birkaç makineye dağıtılır.
Birçok makinede, örneğin arabalarda, her biri birden fazla yerleşik bilgisayar bulunur.
bazıları belirli bir göreve adanmıştır. Çoğu durumda, bu koleksiyonlar
bilgisayarların program yürütmelerini senkronize etmesi gerekir. internet oyunları
birden çok işlemciye dağıtılan başka bir yazılım örneği.

sayfa 602
13.2 Alt Program Düzeyinde Eşzamanlılığa Giriş 581
Eşzamanlılık artık çok sayıda günlük bilgi işlem görevlerinde kullanılmaktadır.
sunucular belge isteklerini eşzamanlı olarak işler. Web tarayıcıları artık sec-
grafik işlemeyi çalıştırmak ve programları yorumlamak için ondary çekirdek işlemciler
belgelere gömülü ming kodu. Her işletim sisteminde var
birçok eşzamanlı süreç her zaman yürütülüyor, kaynakları yönetiyor,
klavyelerden girdi alma, programlardan çıktıları görüntüleme ve okuma
ve harici bellek aygıtlarına yazma. Kısacası, eşzamanlılık bir
bilgi işlemin her yerde bulunan parçası.
13.2 Alt Program Düzeyinde Eşzamanlılığa Giriş
Eşzamanlılık için dil desteği düşünülmeden önce, aşağıdakiler yapılmalıdır:
altında yatan eşzamanlılık kavramlarını ve bunun için gereksinimleri
Bir işe yara. Bu konular bu bölümde ele alınmaktadır.
13.2.1 Temel Kavramlar
Bir görev Eşlik olabilir alt programa benzer bir programın bir birim, bir
aynı programın diğer birimleriyle kira yürütme. Bir programdaki her görev
bir kontrol iş parçacığını destekleyebilir. Görevlere bazen süreçler denir . İçinde
bazı diller, örneğin Java ve C#, belirli yöntemler görev görevi görür. Çok
yöntemler, thread adı verilen nesnelerde yürütülür .
Görevlerin üç özelliği onları alt programlardan ayırır. İlk olarak, bir
görev dolaylı olarak başlatılabilirken, bir alt program açıkça çağrılmalıdır.
İkincisi, bir program birimi bir görevi çağırdığında, bazı durumlarda beklemesine gerek yoktur.
kendi görevine devam etmeden önce yürütmesini tamamlama görevi. Üçüncüsü, ne zaman
bir görevin yürütülmesi tamamlandıysa, kontrol ilgili birime geri dönebilir veya dönmeyebilir.
bu idamı başlattı.
Görevler iki genel kategoriye ayrılır: ağır ve hafif. basitçe
belirtildiğinde, ağır bir görev kendi adres alanında yürütülür. Hafif görevler
hepsi aynı adres alanında çalışır. Hafif görevleri uygulamak daha kolaydır
ağır görevler. Ayrıca, hafif görevler daha verimli olabilir
ağır görevler, çünkü bunların yürütülmesini yönetmek için daha az çaba gerekir.
Bir görev, paylaşılan yerel olmayan değişkenler aracılığıyla diğer görevlerle iletişim kurabilir,
mesaj geçişi veya parametreler aracılığıyla. Bir görev iletişim kurmazsa
programdaki herhangi bir başka görevin yürütülmesini herhangi bir şekilde etkileyen veya etkileyen,
olmak ayrık . Çünkü görevler genellikle simülasyonlar oluşturmak veya çözmek için birlikte çalışır.
sorunlardır ve bu nedenle ayrık değildirler, bir tür iletişim biçimi kullanmaları gerekir.
Yürütmelerini senkronize etmek veya verileri paylaşmak veya her ikisini birden yapmak için.
Senkronizasyon , görevlerin sırasını kontrol eden bir mekanizmadır.
uygulamak. Görevler veri paylaştığında iki tür senkronizasyon gerekir:
işbirliği ve rekabet. İşbirliği senkronizasyonu gerekli
Görev arasındaki A ve görev B görev yaparken bir görev beklemelidir B komple bazılarına
A görevinin yürütülmesinden önceki belirli bir faaliyet , yürütmeye başlayabilir veya devam edebilir. Yarışma
her ikisi de kullanımını gerektirdiğinde, iki görev arasında senkronizasyon gereklidir.

sayfa 603
582
Bölüm 13 Eşzamanlılık
aynı anda kullanılamayan bazı kaynaklar. Spesifik olarak, eğer A görevi gerekiyorsa
erişim paylaşılan veri konumu için x görev yaparken B erişen x , görev A beklemelidir
B görevinin x'i işlemesini tamamlaması için . Yani, işbirliği senkronizasyonu için,
görevlerin, üzerinde çalıştıkları belirli işlemlerin tamamlanmasını beklemesi gerekebilir.
doğru çalışma bağlıdır, oysa rekabet senkronizasyonu için görevler
şu anda herhangi bir görev tarafından başka herhangi bir işlemin tamamlanmasını beklemeniz gerekiyor
belirli paylaşılan verilerde meydana gelir.
Basit bir işbirliği senkronizasyonu biçimi, bir iletişim ile gösterilebilir.
mon problemine üretici-tüketici problemi denir . Bu sorunun kökeni-
içinde bir program biriminin bulunduğu işletim sistemlerinin geliştirilmesine dayanır.
bir veri değeri veya kaynağı üretir ve bir başkası onu kullanır. Üretilen veriler
genellikle üretim birimi tarafından bir depolama tamponuna yerleştirilir ve bundan çıkarılır.
tüketen birim tarafından tampon. Mağazaya gidilecek ve buradan kaldırılacak mağazaların sırası
arabellek senkronize edilmelidir. Tüketici biriminin almasına izin verilmemelidir.
arabellek boşsa, arabellekteki veriler. Aynı şekilde üretici birim de
arabellek doluysa arabelleğe yeni veri yerleştirmesine izin verilir. Bu bir problem
paylaşılan veri yapısının kullanıcıları nedeniyle işbirliği senkronizasyonunun
tampon doğru kullanılacaksa işbirliği yapmalıdır.
Rekabet senkronizasyonu, iki görevin paylaşılan bir
veri yapısını tam olarak aynı anda - yok edebilecek bir durum
paylaşılan verilerin bütünlüğü. Rekabet senkronizasyonunu sağlamak, karşılıklı olarak
paylaşılan verilere özel erişim garanti edilmelidir.
Rekabet sorununu netleştirmek için aşağıdaki senaryoyu göz önünde bulundurun:
poz görevi A TOTAL += 1 ifadesine sahiptir , burada TOTAL paylaşılan bir tam sayıdır
değişken. Ayrıca, B görevinin TOTAL *= 2 ifadesini içerdiğini varsayalım . Görev A
ve görev B aynı anda TOPLAM'ı değiştirmeyi deneyebilir .
Makine dili düzeyinde, her bir görev, işlemini şu şekilde gerçekleştirebilir:
Aşağıdaki üç adımlı süreçle TOPLAM :
1. TOTAL değerini alın .
2. Aritmetik işlemi gerçekleştirin.
3. Yeni değeri TOTAL'a geri koyun .
Daha önce açıklanan işlem göz önüne alındığında, rekabet senkronizasyonu olmadan
TOTAL üzerinde A ve B görevleri tarafından gerçekleştirilen işlemler , dört farklı değerle sonuçlanabilir,
operasyon adımlarının sırasına bağlı olarak. Varsayalım TOPLAM vardır
A veya B onu değiştirmeye çalışmadan önce 3 değerini . A görevi operasyonunu tamamlarsa,
B görevi başlamadan önce , değer 8 olacaktır ve burada uyum olduğu varsayılır.
doğru. Ancak her iki eğer A ve B değerini getir TOTAL ya görev yeni koyar önce
değer geri, sonuç yanlış olacaktır. Eğer bir ilk değeri geri koyar, değer
arasında TOTAL olacak 6 . Bu durum Şekil 13.1'de gösterilmiştir. Eğer B değeri geri koyar
ilk olarak, TOTAL değeri 4 olacaktır . Son olarak, B işlemini daha önce tamamlarsa
A görevi başlar, değer 7 olur . Bu sorunlara yol açan bir durum,
bazen yarış koşulu denir , çünkü iki veya daha fazla görev kullanmak için yarışıyor
paylaşılan kaynak ve programın davranışı hangi göreve bağlıdır
önce gelir (ve yarışı kazanır). Rekabet senkronizasyonunun önemi
şimdi netleşmeli.

sayfa 604
13.2 Alt Program Düzeyinde Eşzamanlılığa Giriş 583
Karşılıklı olarak özel erişim sağlamak için genel bir yöntem (desteklemek için
rekabet senkronizasyonu) paylaşılan bir kaynağa, kaynağı dikkate almaktır.
bir görevin sahip olabileceği bir şey olmak ve yalnızca tek bir görevin sahip olmasına izin vermek
bir seferde. Paylaşılan bir kaynağa sahip olmak için bir görevin onu talep etmesi gerekir. konum
oturum, yalnızca başka bir göreve sahip olmadığında verilecektir. bir görev iken
bir kaynağa sahipse, diğer tüm görevlerin buna erişimi engellenir.
kaynak. Bir görev, sahip olduğu paylaşılan bir kaynakla tamamlandığında,
diğer görevler için kullanılabilir hale getirilebilmesi için bu kaynağı terk etmelidir.
Paylaşılan bir dosyaya karşılıklı olarak özel erişim sağlamanın üç yöntemi
kaynak, Bölüm 13.3'te tartışılan semaforlardır; monitörler,
Bölüm 13.4'te tartışılanlar; ve tartışılan mesaj geçişi
Bölüm 13.5'te.
Senkronizasyon mekanizmaları, görev yürütmeyi geciktirebilmelidir.
Senkronizasyon, ile zorlanan görevlere bir yürütme sırası uygular.
bu gecikmeler. Ömürleri boyunca görevlere ne olduğunu anlamak için,
görev yürütmenin nasıl kontrol edildiğini düşünmeliyiz. İster bir
makinenin tek bir işlemcisi veya birden fazla işlemcisi varsa, her zaman olasılık vardır
işlemcilerden daha fazla görev var. Bir çalışma zamanı sistemi pro-
gram zamanlayıcı adı verilen işlemcilerin görevler arasında paylaşımını yönetir.
Hiçbir zaman kesinti olmadıysa ve görevlerin tümü aynı önceliğe sahip olsaydı,
zamanlayıcı, her göreve 0,1 saniye gibi bir zaman dilimi verebilir ve ne zaman
bir görevin sırası geldi, zamanlayıcı bunun için bir işlemcide yürütülmesine izin verebilir
zaman miktarı. Tabii ki, bunu karmaşıklaştıran birkaç olay var, çünkü
örneğin, senkronizasyon ve giriş veya çıkış işlemleri için görev gecikmeleri.
Çünkü giriş ve çıkış işlemleri işlemcininkine göre çok yavaştır.
hız, bir görevin tamamlanmasını beklerken bir işlemciyi tutmasına izin verilmez
böyle bir operasyondan.
Görevler birkaç farklı durumda olabilir:
1. Yeni : Bir görev, oluşturulduğunda ancak henüz oluşturulmadığında yeni durumundadır.
yürütmeye başladı.
2. Hazır : Hazır bir görev çalışmaya hazırdır ancak şu anda çalışmıyor. Herhangi biri
zamanlayıcı tarafından işlemci zamanı verilmedi veya çalıştırıldı
daha önce ancak 4. Paragrafta açıklanan yollardan biriyle engellendi
Şekil 13.1
için ihtiyaç
yarışma
senkronizasyon
TOTAL3'ün değeri
Görev A
Görev B
Zaman
4
6
Gidip getirmek
TOPLAM
Mağaza
TOPLAM
1 ekle
Gidip getirmek
TOPLAM
Mağaza
TOPLAM
Çarpmak
2 ile

Sayfa 605
584
Bölüm 13 Eşzamanlılık
bu alt bölümün Çalıştırılmaya hazır görevler, bir kuyrukta saklanır.
genellikle göreve hazır kuyruğu olarak adlandırılır .
3. Çalışıyor : Çalışan bir görev, o anda yürütülmekte olan bir görevdir; yani, sahip
bir işlemci ve kodu yürütülüyor.
4. Blocked : Engellenen bir görev yürütülüyor, ancak bu yürütme
birkaç farklı olaydan biri tarafından kesintiye uğradı, en yaygın olanı
bu bir giriş veya çıkış işlemidir. Giriş ve çıkışa ek olarak,
bazı diller, kullanıcı programının bunu belirtmesi için işlemler sağlar.
bir görev engellenmelidir.
5. Ölü : Ölü bir görev artık hiçbir şekilde aktif değildir. Bir görev öldüğünde
yürütme tamamlandı veya program tarafından açıkça öldürüldü.
Bir görevin durumlarının akış şeması Şekil 13.2'de gösterilmektedir.
Görev yürütmede önemli bir konu şudur: Nasıl hazır
o anda çalışmakta olan görevin çalışma durumuna geçmesi için seçilen görev
engellendi veya kimin zaman dilimi doldu? Birkaç farklı algoritma
Şekil 13.2
Görevin akış şeması
devletler
Yeni
Hazır
Koşma
Ölü
Engellendi
Giriş çıkış
Giriş çıkış
Tamamlandı
Tamamlanmış
zamanlanmış
Zaman dilimi
son

Sayfa 606
13.2 Alt Program Düzeyinde Eşzamanlılığa Giriş 585
bazıları belirlenebilir öncelik seviyelerine dayalı olarak bu seçim için kullanılmıştır. bu
seçimi yapan algoritma, zamanlayıcıda uygulanır.
Görevlerin eşzamanlı yürütülmesi ve paylaşılan
kaynaklar canlılık kavramıdır. Sıralı programlar ortamında,
bir program , sonunda yürütmeye devam ederse , canlılık özelliğine sahiptir.
tamamlanmasına yol açar. Daha genel bir ifadeyle, canlılık, eğer bazı
olay - örneğin, programın tamamlanması - olması gerekiyordu, gerçekleşecek, sonunda
müttefik. Yani sürekli ilerleme kaydedilmektedir. Eşzamanlı bir ortamda ve
paylaşılan kaynaklarla, bir görevin canlılığı sona erebilir, yani
program devam edemez ve bu nedenle asla sona ermez.
Örneğin, A görevinin ve B görevinin her ikisinin de paylaşılan X kaynaklarına ihtiyacı olduğunu varsayalım.
ve Y işlerini tamamlamak için. Ayrıca, bu görev varsayalım A kazançları parça bulunmaktadır
bir sion X ve görev B onun eline Y . Bazı yürütme, görev sonrasında A ihtiyaçları
Kaynak Y o istekleri yüzden, devam etmek Y ancak beklemek zorundadır B bültenleri o. Beğenmek-
akıllıca, B görevi X'i ister , ancak A onu serbest bırakana kadar beklemelidir . Ne de vazgeçiyor
sahip olduğu kaynak ve sonuç olarak her ikisi de canlılığını kaybederek bunu garanti altına alır.
programın yürütülmesi hiçbir zaman normal şekilde tamamlanmayacaktır. Bu özel tür
can kaybına kilitlenme denir . Kilitlenme, güvenilirlik için ciddi bir tehdittir
ve bu nedenle programdan kaçınılması, ciddi bir şekilde dikkate alınmasını gerektirir.
hem dil hem de program tasarımı.
sağlamak için bazı dil mekanizmalarını tartışmaya hazırız.
eşzamanlı birim kontrolü
13.2.2 Eşzamanlılık için Dil Tasarımı
Bazı durumlarda, eşzamanlılık kitaplıklar aracılığıyla uygulanır. Bunlar arasında
OpenMP, paylaşılan belleği desteklemek için bir uygulama programlama arayüzü
C, C++ ve Fortran'da çeşitli platformlarda çok işlemcili programlama.
Bu kitaba olan ilgimiz, elbette, eşzamanlılık için dil desteğidir. A
eşzamanlılığı desteklemek için birçok dil tasarlanmıştır,
1960'ların ortalarında PL/I ile ve çağdaş diller Ada dahil
95, Java, C#, F#, Python ve Ruby. 1
13.2.3 Tasarım Sorunları
Eşzamanlılık için dil desteği için en önemli tasarım sorunları
zaten uzun uzadıya tartışılmıştı: rekabet ve işbirliği senkronizasyonu.
Bunlara ek olarak, ikincil öneme sahip birkaç tasarım sorunu vardır.
Bunların arasında öne çıkan, bir uygulamanın görev zamanlamasını nasıl etkileyebileceğidir.
Ayrıca, görevlerin nasıl ve ne zaman yürütülmeye başladığı ve bittiği gibi konular da vardır.
ve nasıl ve ne zaman oluşturuldukları.
1. Python ve Ruby durumlarında programlar yorumlanır, bu nedenle yalnızca mantıksal bağlaç olabilir.
para birimi. Makine birden fazla işlemciye sahip olsa bile, bu programlar bundan yararlanamaz.
birden fazla.

Sayfa 607
586
Bölüm 13 Eşzamanlılık
Eşzamanlılık tartışmamızın kasıtlı olarak uygunsuz olduğunu unutmayın.
ile ilgili dil tasarımı konularının yalnızca en önemlisidir.
eşzamanlılık için destek tartışılır.
Aşağıdaki bölümlerde tasarıma yönelik üç alternatif yanıt tartışılmaktadır.
eşzamanlılık sorunları: semaforlar, monitörler ve ileti geçişi.
13.3 Semaforlar
Bir semafor, senkronizasyon sağlamak için kullanılabilen basit bir mekanizmadır.
görevlerin belirlenmesi. Semaforlar sağlamak için erken bir yaklaşım olsa da
senkronizasyon, hem çağdaş dillerde hem de
kitaplık tabanlı eşzamanlılık destek sistemleri. Aşağıdaki paragraflarda, biz
semaforları tanımlar ve bu amaç için nasıl kullanılabileceğini tartışır.
13.3.1 Giriş
Karşılıklı dışlama yoluyla rekabet senkronizasyonunu sağlamak amacıyla
Edsger Dijkstra, paylaşılan veri yapılarına erişim için semaforlar tasarladı.
1965 (Dijkstra, 1968b). İşbirliği sağlamak için semaforlar da kullanılabilir
senkronizasyon.
Bir veri yapısına sınırlı erişim sağlamak için etrafına korumalar yerleştirilebilir.
yapıya erişen kod. Bir koruma , izin veren dilsel bir cihazdır.
yalnızca belirtilen koşul doğru olduğunda yürütülecek korunan kod. Böyle,
yalnızca bir görevin paylaşılan bir veri yapısına erişmesine izin vermek için bir koruma kullanılabilir
zamanında. Bir semafor, bir korumanın bir uygulamasıdır. Spesifik olarak, bir sema-
phore , bir tamsayı ve görevi depolayan bir kuyruktan oluşan bir veri yapısıdır.
Tanımlayıcılar. Bir görev açıklayıcısı , bir veri yapısı olduğunu saklar ilgili tüm
bir görevin yürütme durumu hakkında bilgi.
Bir koruma mekanizmasının ayrılmaz bir parçası, hepsinin sağlanması için bir prosedürdür.
korunan kodun çalıştırılmaya çalışılması sonunda gerçekleşir. Tipik
yaklaşım, erişim verilemediğinde ortaya çıkan erişim taleplerine sahip olmaktır.
daha sonra izin verilen görev tanımlayıcı kuyruğunda saklanmalıdır.
korunan kodu bırakın ve çalıştırın. Bir semaforun sahip olması gereken sebep budur.
hem bir sayaç hem de bir görev tanımlayıcı kuyruğu.
Semaforlar için sağlanan sadece iki işlem orijinal olarak adlandırılmıştır.
P ve V, Dijkstra tarafından, iki Hollandaca kelime olan passeren (geçmek) ve vrygeren'den sonra
(serbest bırakmak için) (Andrews ve Schneider, 1983). Bunlara bekleme ve
Release , sırasıyla bu bölümün geri kalanında.
13.3.2 İşbirliği Senkronizasyonu
Bu bölümün büyük bölümünde, tarafından kullanılan paylaşılan bir arabellek örneğini kullanıyoruz.
sağlamaya yönelik farklı yaklaşımları göstermek için üreticiler ve tüketiciler
işbirliği ve rekabet senkronizasyonu. İşbirliği senkronizasyonu için-
Böyle bir arabellek, hem boş sayıyı kaydetmenin bir yoluna sahip olmalıdır.

Sayfa 608
13.3 Semaforlar 587
tampondaki pozisyonlar ve doldurulmuş pozisyonların sayısı (tampon
taşma ve taşma). Bir semaforun karşı bileşeni kullanılabilir
bu amaç için. Bir semaforu değişken örneğin, emptyspots -yapabilirsiniz
paylaşılan bir arabellekteki boş konumların sayısını korumak için sayacını kullanın.
fer üretici ve tüketiciler ve başka-ki tarafından kullanılan, fullspots -Can
tampondaki doldurulmuş konumların sayısını korumak için sayacını kullanın. bu
Bu semaforların kuyrukları, daha önce yapılmış görevlerin tanımlayıcılarını depolayabilir.
arabelleğe erişim için beklemeye zorlanır. Boş noktaların kuyruğu depolayabilir
arabellekte mevcut pozisyonları bekleyen üretici görevleri; kuyruk
dolu noktalar , değerlerin içine yerleştirilmesini bekleyen tüketici görevlerini depolayabilir
tampon.
Örnek arabelleğimiz, tüm verilerin içinde bulunduğu soyut bir veri türü olarak tasarlanmıştır.
DEPOSIT alt programı aracılığıyla ara belleğe girer ve tüm veriler
FETCH alt programı aracılığıyla arabellek . MEVDUAT alt program ihtiyaçları sadece
boş nokta olup olmadığını görmek için boş noktalar semaforuyla kontrol etmek için
pozisyonlar. En az bir tane varsa, DEPOSIT ile devam edebilir ;
boş noktaların sayacını azaltmanın yan etkisi vardır . tampon ise
e Arayan dolu ÖDEMELER'den beklemek yapılmalıdır emptyspots kuyrukta
boş bir yerin müsait olması için. Ne zaman MEVDUAT tamamlandığında,
DEPOSIT alt programı, tam noktalar semaforunun sayacını artırır
arabellekte doldurulmuş bir konum daha olduğunu belirtmek için.
FETCH alt program karşıt dizisine sahiptir YATAĞININ . kontrol eder
arabelleğin en az bir tane içerip içermediğini görmek için tam noktalar semaforu
kalem. Varsa, bir öğe kaldırılır ve boş noktalar semaforunun
sayaç 1 artırılır. Arabellek boşsa, çağıran görev
bir öğe görünene kadar beklemek için fullspots kuyruğu. Ne zaman FETCH , bunu bittikten
boş noktaların sayacını artırmak gerekir .
Semafor türleri üzerindeki işlemler genellikle doğrudan değildir - yapılır
bekle ve bırak alt programları aracılığıyla . Bu nedenle, DEPOZİTO ancak operasyonel
az önce açıklanan işlem aslında kısmen bekleme çağrıları ile gerçekleştirilir ve
serbest bırakmak . Bekle ve bırak özelliğinin göreve hazır duruma erişebilmesi gerektiğini unutmayın.
sıra.
Bekleme semafor alt program belirli bir bölgesinin sayacı test etmek için kullanılır
semafor değişkeni. Değer sıfırdan büyükse, arayan kişi şunları yapabilir:
onun çalışması. Bu durumda, semafor değişkeninin sayaç değeri dec-
sayılan her şeyden bir tane daha az olduğunu belirtmek için tekrarladı. Eğer
sayacın değeri sıfır, arayan kişi bekleme kuyruğuna yerleştirilmelidir
semafor değişkeninin ve işlemcinin bir başkasına verilmesi gerekir.
hazır görev.
Salma semafor alt program diğer bazı izin vermek için bir görev tarafından kullanılan
Belirtilen semafor değişkeninin sayacı ne olursa olsun birine sahip olma görevi
sayar. Belirtilen semafor değişkeninin kuyruğu boşsa, bu şu anlama gelir:
hiçbir görev beklemiyor, yayın sayacını artırır (bir görev olduğunu belirtmek için)
şu anda mevcut olan kontrol edilen her şeyden daha fazlası). eğer bir veya daha fazla
görevler bekliyor, yayın bunlardan birini semafor kuyruğundan
hazır kuyruk.

Sayfa 609
588
Bölüm 13 Eşzamanlılık
Bekle ve bırak ile ilgili kısa sözde kod açıklamaları aşağıdadır :
bekle(aSemafor)
eğer aSemaphore ‘ın sayaç > 0 ardından
Eksiltme aSemaphore ‘in karşı
Başka
arayanı aSemaphore'un kuyruğuna koy
kontrolü hazır bir göreve aktarmaya çalışmak
(görev hazır kuyruğu boşsa kilitlenme oluşur)
eğer son
yayın(aSemafor)
eğer aSemaphore bireyin kuyruğu boş ( hiçbir görev bekliyor ) daha sonra
Arttırma aSemaphore ‘in karşı
Başka
çağıran görevi göreve hazır kuyruğa koyun
aSemaphore'un kuyruğundan bir göreve kontrolü aktarma
son
Artık işbirliği senkronizasyonunu uygulayan bir örnek program sunabiliriz.
paylaşılan bir arabellek için kronizasyon. Bu durumda, paylaşılan arabellek tamsayı depolar
değerler ve mantıksal olarak dairesel bir yapıdır. tarafından kullanılmak üzere tasarlanmıştır.
çoklu üretici ve tüketici görevleri.
Aşağıdaki sözde kod, üreticinin tanımını gösterir ve
sümer görevleri. Tampon taşmasına karşı garanti etmek için iki semafor kullanılır veya
taşma, böylece işbirliği senkronizasyonu sağlar. tampon olduğunu varsayalım
BUFLEN uzunluğuna sahip ve onu gerçekten manipüle eden rutinler zaten var
olarak FETCH ve MEVDUAT . Bir semaforun sayacına erişimler belirtildi
nokta gösterimi ile. Örneğin, fullspots bir semafor ise, kendi counter
fullspots.count tarafından başvurulur .
semafor dolu noktalar, boş noktalar;
fullspots.count = 0;
emptyspots.count = BUFLEN;
görev yapımcısı;
döngü
-- DEĞER üret --
bekle(boş noktalar); {bir boşluk bekleyin}
MEVDUAT(DEĞER);
yayın(dolu noktalar); {dolu alanları artırın}
son döngü ;
son üretici;
görev tüketicisi;
döngü
bekle(dolu noktalar); { boş olmadığından emin olun }

Sayfa 610
13.3 Semaforlar 589
FETCH(DEĞER);
yayın(boş noktalar); { boşlukları artır }
-- DEĞER tüket --
son döngü
son tüketici;
Semafor dolu noktaları , tüketici görevinin beklemek için sıraya alınmasına neden olur
şu anda boşsa bir arabellek girişi için. Semafor boş noktaları neden olur
yapımcı görev eğer o tamponu içinde boş bir alana beklemek kuyruklanacak
şu anda dolu.
13.3.3 Yarışma Senkronizasyonu
Tampon örneğimiz rekabet senkronizasyonu sağlamaz. Erişim
yapı ek bir semafor ile kontrol edilebilir. bu semafor
hiçbir şeyi sayması gerekmez, ancak sayacıyla,
tampon şu anda kullanılıyor. Bekleme ifadesi yalnızca erişim sağlar
semaforun sayacı, paylaşılan arabelleğin olmadığını gösteren 1 değerine sahiptir.
şu anda erişiliyor. Semaforun sayacı 0 değerine sahipse ,
geçerli erişim gerçekleşir ve görev semaforun kuyruğuna yerleştirilir.
Semaforun sayacının 1 olarak başlatılması gerektiğine dikkat edin . kuyrukları
Kuyruk kullanımı başlamadan önce semaforlar her zaman boş olarak başlatılmalıdır.
Kullanılan gibi yalnızca ikili değerli bir sayaç gerektiren bir semafor
Aşağıdaki örnekte rekabet senkronizasyonunu sağlamak için
ikili semafor .
Aşağıdaki örnek sözde kod, semaforların kullanımını göstermektedir.
eşzamanlı olarak hem rekabet hem de işbirliği senkronizasyonu sağlar.
paylaşılan arabelleğe erişildi. Erişim semafor karşılıklı sağlamak için kullanılır
arabelleğe özel erişim. Birden fazla olabileceğini unutmayın
üretici ve birden fazla tüketici.
semafor erişimi, dolu noktalar, boş noktalar;
erişim.sayısı = 1;
fullspots.count = 0;
emptyspots.count = BUFLEN;
görev yapımcısı;
döngü
-- DEĞER üret --
bekle(boş noktalar); {bir boşluk bekleyin}
bekle(erişim);
{ erişim için bekleyin }
MEVDUAT(DEĞER);
yayın (erişim); { erişimden vazgeç }
yayın(dolu noktalar); {dolu alanları artırın}
son döngü ;
son üretici;

Sayfa 611
590
Bölüm 13 Eşzamanlılık
görev tüketicisi;
döngü
bekle(dolu noktalar); { boş olmadığından emin olun }
bekle(erişim);
{ erişim için bekleyin }
FETCH(DEĞER);
yayın (erişim); { erişimden vazgeç }
yayın(boş noktalar); { boşlukları artır }
-- DEĞER tüket --
son döngü
son tüketici;
Bu örneğe kısa bir bakış, bir sorun olduğuna inanmasına neden olabilir.
Spesifik olarak, bir görev beklerken wait(access) çağrısında bulunduğunu varsayalım .
tüketici , başka bir görev, paylaşılan arabellekten son değeri alır. şans
doğal olarak, bu olamaz, çünkü wait(fullspots) içinde bir değer saklı tutar.
tam nokta sayacını azaltarak onu çağıran görevin arabelleği .
Semaforların şimdiye kadar anlaşılmayan çok önemli bir yönü vardır.
tartışıldı. Rekabet sorununun önceki açıklamasını hatırlayın
senkronizasyon: Paylaşılan veriler üzerindeki işlemler çakışmamalıdır. eğer bir saniye
işlem daha önceki bir işlem devam ederken başlar, paylaşılan
veriler bozulabilir. Bir semaforun kendisi paylaşılan bir veri nesnesidir, dolayısıyla
semaforlar üzerindeki işlemler de aynı soruna açıktır. o
bu nedenle semafor işlemlerinin kesintisiz olması esastır. Birçok
bilgisayarlar özel olarak tasarlanmış kesintisiz talimatlara sahiptir.
semafor işlemleri için. Bu tür talimatlar mevcut değilse, o zaman
rekabet senkronizasyonu sağlamak için semaforlar ile ciddi bir sorundur.
basit bir çözüm yok.
13.3.4 Değerlendirme
İşbirliği senkronizasyonu sağlamak için semaforların kullanılması güvenli olmayan bir
programlama ortamı Kordonu statik olarak kontrol etmenin bir yolu yoktur.
hangi programın semantiğine bağlı olarak kullanımlarının doğruluğu
görünürler. Tampon örnekte, bırakarak bekleme (emptyspots) devlet
gündeme gelebilecektir yapımcı görev arabellek taşmasına neden olur. dışarıda bırakmak
tüketici görevinin wait(fullspots) ifadesi arabelleğe neden olur
taşma. Yayınlardan herhangi birinin dışında bırakılması kilitlenmeye neden olur. Bunlar
işbirliği senkronizasyon hatalarıdır.
Semaforların işbirliğini sağlamada neden olduğu güvenirlik sorunları
senkronizasyon, rekabet senkronizasyonu için kullanıldığında da ortaya çıkar.
Her iki görevde de wait(access) ifadesini dışarıda bırakmak güvensizliğe neden olabilir.
arabelleğe erişim. Release(access) ifadesini her ikisinde de dışarıda bırakmak
görev kilitlenme ile sonuçlanır. Bunlar rekabet senkronizasyonu hatalarıdır. Değil-
Per Brinch Hansen (1973), semafor kullanmanın tehlikesini şöyle yazmıştır:
semafor, ideal bir programcı için zarif bir senkronizasyon aracıdır.
asla hata yapmaz." Ne yazık ki, ideal programcılar nadirdir.

Sayfa 612
13.4 Monitörler 591
13.4 Monitörler
Eşzamanlı bir ortamda semaforların bazı sorunlarına bir çözüm
Ronment, paylaşılan veri yapılarını operasyonları ile kapsüllemektir ve
temsillerini gizlemek, yani paylaşılan veri yapılarını soyut hale getirmek
bazı özel kısıtlamalara sahip veri türleri. Bu çözüm rekabet sağlayabilir
sorumluluğu devrederek semaforsuz tition senkronizasyonu
çalışma zamanı sistemine senkronizasyon.
13.4.1 Giriş
Veri soyutlama kavramları formüle edilirken, insanlar
bu çabaya dahil olan, aynı kavramları eşzamanlı olarak paylaşılan verilere uyguladı.
monitörler üretmek için programlama ortamları. Per Brinch'e göre
Hansen (Brinch Hansen, 1977, s. xvi), Edsger Dijkstra 1971'de şunu önerdi:
paylaşılan veriler üzerindeki tüm senkronizasyon işlemleri tek bir programda toplanır
birim. Brinch Hansen (1973), bu kavramı
işletim sistemleri. Ertesi yıl, Hoare (1974) bu yapıları adlandırdı.
monitörler .
Monitörleri dahil eden ilk programlama dili Concur-
kira Pascal (Brinch Hansen, 1975). Modula (Wirth, 1977), CSP/k (Holt ve diğerleri,
1978) ve Mesa (Mitchell ve diğerleri, 1979) ayrıca monitörler sağlar. düşünce arasında
porary dilleri, monitörler Ada, Java ve C# tarafından desteklenir ve bunların tümü
bu bölümde daha sonra tartışılacaktır.
13.4.2 Yarışma Senkronizasyonu
Monitörlerin en önemli özelliklerinden biri, paylaşılan verilerin yerleşik olmasıdır.
istemci birimlerinden herhangi biri yerine monitörde. programcı yapar
kullanımı yoluyla paylaşılan verilere karşılıklı olarak özel erişimi senkronize etmemek
semaforlar veya diğer mekanizmalar. Erişim mekanizmaları bir parçası olduğu için
monitör, senkronizasyonu garanti etmek için bir monitörün uygulanması yapılabilir.
bir seferde yalnızca bir erişime izin vererek erişim. Prosedürleri izlemek için çağrılar
monitör o sırada meşgulse örtük olarak engellenir ve bir kuyrukta saklanır
aramanın.
13.4.3 İşbirliği Senkronizasyonu
Paylaşılan verilere karşılıklı olarak özel erişim bir monitöre özgü olsa da,
süreçler arasındaki işbirliği hala programcının görevidir. özellikle
lar, programcı paylaşılan bir arabelleğin deneyimlenmediğini garanti etmelidir.
taşma veya taşma. Farklı diller, farklı programlama yolları sağlar.
hepsi semaforlarla ilgili olan işbirliği senkronizasyonu.
Dört görev ve senkronize sağlayan bir monitör içeren bir program
eşzamanlı olarak paylaşılan bir arabelleğe erişim, Şekil 13.3'te gösterilmiştir. Bu rakamda,

Sayfa 613
592
Bölüm 13 Eşzamanlılık
monitör arabirimi, ek etiketli iki kutu olarak gösterilir ve
kaldır (verilerin eklenmesi ve çıkarılması için). monitör tam olarak görünüyor
soyut bir veri türü gibi—sınırlı erişime sahip bir veri yapısı—ki bu
bir monitördür.
13.4.4 Değerlendirme
Monitörler, rekabet senkronizasyonu sağlamanın daha iyi bir yoludur.
semaforlar, öncelikle semaforların sorunları nedeniyle, tartışıldığı gibi
Bölüm 13.3. İşbirliği senkronizasyonu hala monitörlerle ilgili bir sorundur,
monitörlerin Ada ve Java uygulamaları tartışıldığında netleşeceği gibi
aşağıdaki bölümlerde.
Semaforlar ve monitörler, eşzamanlılığı ifade etmede eşit derecede güçlüdür
kontrol—semaforlar monitörleri uygulamak için kullanılabilir ve monitörler
semaforları uygulamak için kullanılır.
Ada, monitörleri uygulamak için iki yol sunar. Ada 83 bir genel içerir
monitörleri desteklemek için kullanılabilecek görev modeli. Ada 95 bir temizleyici ekledi
ve korumalı nesneler adı verilen monitörler oluşturmanın daha verimli bir yolu . Her ikiside
bu yaklaşımlar, ileti iletimini, fikir birliğini desteklemek için temel bir model olarak kullanır.
rency. Mesaj iletme modeli, eşzamanlı birimlerin dağıtılmasına izin verir,
hangi monitörler izin vermez. Mesaj geçişi Bölüm 13.5'te açıklanmıştır; Ada
mesaj geçişi desteği Bölüm 13.6'da tartışılmaktadır.
Java'da, soyut olarak tasarlanmış bir sınıfta bir monitör uygulanabilir.
veri türü, paylaşılan veriler türdür. Nesnelere erişim
sınıf , erişime senkronize değiştirici eklenerek kontrol edilir.
yöntemler. Java'da yazılmış paylaşılan arabellek için bir monitör örneği:
Bölüm 13.7.4'te verilmiştir.
Şekil 13.3
kullanan bir program
kontrol etmek için izlemek
paylaşılan erişim
tampon
İşlem
ALT1
İşlem
SUB2
İşlem
SUB3
İşlem
SUB4
Sokmak
monitör
programı
Kaldırmak
B
sen
F
F
E
r

Sayfa 614
13.5 Mesaj Geçişi 593
C#, uygulamak için tasarlanmış önceden tanımlanmış bir Monitor sınıfına sahiptir.
monitörler.
13.5 Mesaj Geçişi
Bu bölüm, mesaj iletiminin temel kavramlarını eşzamanlı olarak tanıtmaktadır.
rency. Bu mesaj geçişi kavramının mesajla ilgisi olmadığına dikkat edin.
yöntemleri uygulamak için nesne yönelimli programlamada kullanılan geçiş.
13.5.1 Giriş
Mesaj için yetenek sağlayan dilleri tasarlamaya yönelik ilk çabalar
Eşzamanlı görevler arasında Brinch Hansen (1978) ve Hoare
(1978). Mesaj iletiminin bu öncü geliştiricileri aynı zamanda bir teknoloji geliştirdiler.
aynı anda birden çok kez ne yapılması gerektiği sorununu çözmek için nique
belirli bir görevle iletişim kurmak için diğer görevler tarafından istekler yapıldı. Öyleydi
adaleti sağlamak için bir tür belirsizliğin gerekli olduğuna karar verdi
Bu isteklerden hangisinin önce alınacağını seçerken. bu adalet
çeşitli şekillerde tanımlanabilir, ancak genel olarak, tüm talep sahiplerinin
belirli bir görevle iletişim kurmak için eşit bir şans sağlanır (varsayılan
her istekte bulunanın aynı önceliğe sahip olması). için deterministik olmayan yapılar
korumalı komutlar olarak adlandırılan ifade düzeyinde kontrol, Dijkstra tarafından tanıtıldı
(1975). Korunan komutlar Bölüm 8'de tartışılmaktadır. Korunan komutlar
mesaj geçişini kontrol etmek için tasarlanmış yapının temelidir.
13.5.2 Senkron Mesaj Geçişi Kavramı
Mesaj geçişi senkron veya asenkron olabilir. Burada tarif ediyoruz
senkronize mesaj geçişi. Senkron mesaj geçişinin temel konsepti
Görevlerin genellikle meşgul olması ve meşgul olduklarında kesintiye uğramamasıdır.
diğer birimler. A görevinin ve B görevinin her ikisinin de yürütülmekte olduğunu ve A'nın yapmak istediğini varsayalım .
B'ye bir mesaj gönderin . Açıkça, B meşgulse, başka birine izin vermek istenmez.
kesme görevi. Bu, B'nin mevcut işlemesini bozar . Üstelik,
mesajlar genellikle alıcıda ilişkili işlemeye neden olur;
diğer işlemler eksikse mantıklı olun. Alternatif, bir
Bir görevin hazır olduğunda diğer görevlere belirtmesine izin veren dilsel mekanizma
mesajları almak için. Bu yaklaşım, talimat veren bir yönetici gibidir.
sekreteri gelen tüm aramaları başka bir etkinliğe, belki de bir
önemli konuşma tamamlandı. Daha sonra, mevcut konuşma
tamamlandı, yönetici sekretere şimdi konuşmaya istekli olduğunu söyler
beklemeye alınan arayanlardan birine.
Bir görev, bir noktada yürütülmesini askıya alabileceği şekilde tasarlanabilir,
ya boşta olduğu için ya da başka bir birimden bilgiye ihtiyaç duyduğu için
önce devam edebilir. Bu, önemli bir aramayı bekleyen bir kişi gibidir.
Bazı durumlarda oturup beklemekten başka yapacak bir şey yoktur. Ancak, eğer görev A

Sayfa 615
594
Bölüm 13 Eşzamanlılık
B görevi bu mesajı gönderdiğinde bir mesaj bekliyorsa , mesaj
iletilmek. Mesajın bu gerçek aktarımına randevu denir .
Bir randevunun yalnızca hem gönderici hem de alıcı isterse gerçekleşebileceğini unutmayın.
olmak. Bir buluşma sırasında, mesajın bilgileri iletilebilir.
bir veya her iki yönde ted.
Görevlerin hem işbirliği hem de rekabet senkronizasyonu bir araya getirilebilir.
aşağıda açıklandığı gibi, mesaj iletme modeliyle dikkatli bir şekilde işlenir
Bölüm.
13.6 Eşzamanlılık için Ada Desteği
Bu bölüm, Ada tarafından sağlanan eşzamanlılık desteğini açıklar. Ada 83
yalnızca senkronize mesaj geçişini destekler.
13.6.1 Temel bilgiler
Görevler için Ada tasarımı kısmen Brinch Hansen ve
Bu mesaj geçişinde Hoare tasarım temelidir ve nondeterminizm kullanılır
Mesaj gönderen görevler arasından seçim yapmak için
Tam Ada görevlendirme modeli karmaşıktır ve aşağıdaki tartışma
sınırlıdır. Buradaki odak, senkronize olanın Ada versiyonunda olacaktır.
mesaj iletme mekanizması.
Ada görevleri, monitörlerden daha aktif olabilir. Monitörler pasif varlıklardır
depoladıkları paylaşılan veriler için yönetim hizmetleri sağlayan sağlarlar
hizmetleri, ancak yalnızca bu hizmetler talep edildiğinde. alıştığında
paylaşılan verileri yönetin, Ada görevleri, içinde bulunabilecek yöneticiler olarak düşünülebilir.
yönettikleri kaynakla. Birkaç mekanizmaya sahiptirler, bazıları belirleyicidir.
Rakipler arasında seçim yapmalarına izin veren istik ve bazı deterministik olmayan
kaynaklarına erişim talepleri.
Ada görevlerinin sözdizimsel biçimi Ada paketlerininkine benzer. Orası
ikisi de aynı ada sahip iki parçadır - bir belirtim bölümü ve bir gövde bölümü.
Bir görevin arayüzü, giriş noktaları veya mesajları kabul edebileceği konumlardır.
diğer görevlerden bilgeler. Bu giriş noktaları arayüzünün bir parçası olduğu için,
bir görevin belirtim bölümünde listelenmeleri doğaldır. Çünkü bir randevu-
vous bilgi alışverişini içerebilir, mesajların parametreleri olabilir;
bu nedenle, görev giriş noktaları, aynı zamanda olması gereken parametrelere de izin vermelidir.
spesifikasyon bölümünde açıklanmıştır. Görünüşte, bir görev belirtimi benzerdir
soyut bir veri türü için paket belirtimine.
Ada görev belirtimine bir örnek olarak aşağıdaki kodu göz önünde bulundurun:
In-mode sahip Entry_1 adlı tek bir giriş noktası içeren
parametre:
görev Task_Örneği :
giriş Entry_1 (Ürün: içinde Integer);
son Task_Example;

Sayfa 616
13.6 Eşzamanlılık için Ada Desteği 595
Bir görev birimi, giriş noktalarının bazı sözdizimsel biçimlerini içermelidir.
o görevin belirtim bölümündeki giriş maddelerine karşılık gelir . Adana'da bunlar
Görev gövdesi giriş noktaları, görev birimi tarafından tanıtılan maddelerle belirlenir.
ayrılmış kelimeyi kabul et . Bir kabul maddesi , durum aralığı olarak tanımlanır.
Rezerve edilmiş kelimeyi kabul et ile başlayan ve eşleşen ile biten
ayrılmış kelimeyi bitir . kabul cümleciklerinin kendileri nispeten basittir, ancak diğer
içine gömülebilecekleri yapılar, anlambilimlerini karmaşık hale getirebilir.
Basit bir kabul maddesi şu şekildedir:
giriş_adı kabul et ( resmi parametreler ) yap
. . .
son ENTRY_NAME ;
Kabul girdi adı bir in adıyla eşleşen giriş birligidir yan tümcesi
ated görev belirtimi bölümü. İsteğe bağlı parametreler şu araçları sağlar:
arayan ve aranan görev arasındaki iletişim verileri. İfadeler
do ile bitiş arasında, işlem sırasında gerçekleşen işlemleri tanımlar.
buluşma. Bu ifadeler birlikte kabul cümlesi gövdesi olarak adlandırılır .
Gerçek buluşma sırasında gönderen görevi askıya alınır.
Bir kabul maddesi, istekli olmadığına dair bir mesaj aldığında
hangi nedenle olursa olsun kabul etmek için gönderen görevi, gönderilene kadar askıya alınmalıdır.
Kabul cümlesi alıcı görevinde mesajı kabul etmeye hazırdır. Tabii ki,
kabul deyimi ayrıca mesaj gönderen gönderen görevlerini de hatırlamalıdır.
ki kabul edilmedi. Bu amaçla, bir görevdeki her kabul deyiminin bir
başarısız olan diğer görevlerin bir listesini saklayan onunla ilişkili kuyruk
ile iletişim kurmaya çalıştı.
Spesifikasyonu verilen görevin iskelet yapısı aşağıdadır.
Önceden:
görev gövdesi Task_Example (şimdiki değeri)
başlamak
döngü
kabul : Entry_1 (Öğe içinde Integer) do
. . .
son Entry_1;
son döngü ;
son Task_Example;
Kabul bu görev vücudun hükmü uygulanmasıdır girişi
görev belirtiminde Giriş_1 adlı . Eğer yürütülmesi Task_Example
başlar ve diğer herhangi bir görev gönderilmeden önce Giriş_1 kabul cümlesine ulaşır
Entry_1'e bir mesaj , Task_Example askıya alındı. Başka bir görev gönderilirse
Task_Example kabul edildiğinde askıya alınırken Entry_1'e bir mesaj ,
buluşma gerçekleşir ve kabul yan tümcesi gövdesi yürütülür. Daha sonra, nedeniyle
döngü, yürütme kabule geri döner . Başka bir görev göndermediyse
Entry_1'e ileti gönderildiğinde , sonraki iletiyi beklemek için yürütme yeniden askıya alındı.

Sayfa 617
596
Bölüm 13 Eşzamanlılık
Bu basit örnekte bir buluşma iki temel yolla gerçekleşebilir. Öncelikle,
alıcı görevi Task_Example , başka bir görevin bir mesaj göndermesini bekliyor olabilir
Entry_1 girişine mesaj . Mesaj gönderildiğinde, randevu
meydana gelmek. Daha önce açıklanan durum budur. İkincisi, alıcı görevi
bir randevuyla veya ilgili olmayan başka bir işlemle meşgul
bir randevu, başka bir görev aynı girişe mesaj göndermeye çalıştığında.
Bu durumda, alıcı bunu kabul etmekte özgür olana kadar gönderici askıya alınır.
bir randevuda mesaj. Alıcı meşgulken birden fazla mesaj gelirse,
gönderenler randevu için sıralarını beklemek üzere kuyruğa alınır.
Az önce açıklanan iki randevu zaman çizelgesi diyagramıyla gösterilmiştir.
gram Şekil 13.4.
Görevlerin giriş noktaları olması gerekmez. Bu tür görevlere aktör görevleri denir çünkü
işlerini yapmak için randevu beklemezler. Aktör görevleri
onlara mesaj göndererek diğer görevlerle buluşma. aktörün aksine
görevler, bir görevin kabul cümlecikleri olabilir, ancak bunların dışında herhangi bir kodu olamaz.
tümceleri kabul edin , böylece yalnızca diğer görevlere tepki verebilir. Böyle bir göreve denir
sunucu görevi .
Başka bir göreve mesaj gönderen bir Ada görevi, girişi bilmelidir.
adı bu görevde. Ancak bunun tersi doğru değildir: Bir görev girişinin
Şekil 13.4
Randevu için iki yol
ile Task_Example
meydana gelebilir
Kabul
Kabul
Görev_Örneği
Görev_Örneği
Görev_Örneği
Gönderen
Gönderen
Görev_Örneği

Sayfa 618
13.6 Eşzamanlılık için Ada Desteği 597
mesajları kabul edeceği görevin adını bilin. bu asimetri
CSP veya Communicat- olarak bilinen dilin tasarımına zıttır.
Ardışık Süreçler (Hoare, 1978). Mesajı da kullanan CSP'de-
eşzamanlılık modelini geçerken, görevler yalnızca açıkça adlandırılmış iletileri kabul eder
görevler. Bunun dezavantajı, görev kitaplıklarının oluşturulamamasıdır.
Genel kullanım.
A görevinin içinde bulunduğu bir randevuyu tanımlamanın olağan grafik yöntemi.
B görevine bir mesaj gönderir Şekil 13.5'te gösterilmiştir.
Görevler, bir paketin, alt programın veya alt programın bildirim bölümünde bildirilir.
engellemek. Statik olarak oluşturulmuş görevler 2 , durumla aynı anda yürütülmeye başlar.
bu bildirimsel kısmın eklendiği kodda yer alır. Örneğin, bir görev
bir ana programda bildirilen, ilk durumla aynı anda yürütmeye başlar.
ana programın kod gövdesinde yer alır. olan görev sonlandırma,
karmaşık konu, bu bölümün ilerleyen kısımlarında tartışılacaktır.
Görevlerin herhangi bir sayıda girişi olabilir. ilişkili olduğu sıra
Görevde görünen kabul cümlecikleri, mesajların hangi sırayla alınabileceğini belirler.
kabul edilmiş. Bir görevin birden fazla giriş noktası varsa ve bunları yapabilmelerini gerektiriyorsa
mesajları herhangi bir sırayla almak için görev, içine almak için bir seçim ifadesi kullanır
girişler. Örneğin, bir görevin bir banka memurunun faaliyetlerini modellediğini varsayalım,
Müşterilere bankanın içindeki bir istasyonda hizmet vermesi ve aynı zamanda hizmet vermesi gereken
2. Görevler dinamik olarak da oluşturulabilir, ancak bu tür görevler burada kapsanmamaktadır.
Şekil 13.5
grafiksel
temsili bir
randevunun neden olduğu bir
görevden gönderilen mesaj
A'dan B görevine
(değer)
kabul
kabul

Sayfa 619
598
Bölüm 13 Eşzamanlılık
müşteriler bir sürücü penceresinde. Aşağıdaki iskelet memuru görevi, bir
yapıyı seçin :
Görev içeriğinin Teller olduğunu
başlamak
döngü
Seçme
kabul Drive_Up ( biçimsel parametreleri ) yapmak
. . .
son Drive_Up;
. . .
veya
Walk_Up'ı kabul et ( resmi parametreler ) yap
. . .
son Walk_Up;
. . .
son seçim ;
son döngü ;
son Teller;
Bu görev, orada iki kabul hükümler, Walk_Up ve Drive_Up her biri
ilişkili bir kuyruğa sahip olan. Eylem seçmek yürütüldüğünde,
iki kabul cümlesi ile ilişkili kuyrukları incelemektir . eğer biri
kuyruklar boş, ancak diğerinde en az bir bekleyen mesaj var (cus-
tomer), bekleyen mesaj veya mesajlarla ilişkili kabul maddesi
alınan ilk mesajı gönderen görevle bir randevusu var.
Her iki kabul cümlesinin de boş kuyrukları varsa, seçim aşağıdakilerden biri olana kadar bekler.
girişler denir. Her iki kabul cümlesinin de boş olmayan kuyrukları varsa, biri
arasında kabul maddelerine nondeterministically bir buluşma olanı seçmektedir
arayanlardan biriyle. Döngü, select deyimini yürütülmeye zorlar.
tekrar tekrar, sonsuza kadar.
arasında kabul fıkra işaretleri kodun sonuna o atar ya
kabul deyiminin biçimsel parametrelerine başvurur. Kod, varsa
herhangi bir arasında olduğunu kabul maddesi ve bir sonraki veya (veya seçmek sonunda eğer,
kabul deyimine de sonuncusu seçme denir) genişletilmiş
kabul cümlesi . Genişletilmiş kabul yan tümcesi yalnızca asso-
ciated (hemen önceki) kabul cümlesi yürütülür. Bu yürütme
genişletilmiş kabul maddesi randevunun bir parçası değildir ve gerçekleşebilir
çağıran görevin yürütülmesiyle eşzamanlı olarak. gönderen askıya alındı
randevu sırasında, ancak bittiğinde tekrar hazır kuyruğa alınır.
kabul şartı ulaşılır. Bir kabul maddesinin resmi parametreleri yoksa,
do uç gerekli değildir, ve kabul , bir tamamen oluşabilir madde
genişletilmiş kabul maddesi Böyle bir kabul maddesi yalnızca aşağıdakiler için kullanılacaktır:
senkronizasyon. Genişletilmiş kabul maddeleri Buf_Task'ta gösterilmektedir
Bölüm 13.6.3'teki görev.

Sayfa 620
13.6 Eşzamanlılık 599 için Ada Desteği
13.6.2 İşbirliği Senkronizasyonu
Her kabul maddesi, bir ne zaman maddesi şeklinde eklenmiş bir korumaya sahip olabilir ,
bu randevuyu geciktirebilir. Örneğin,
Dolu olmadığında (Tampon) =>
Depozitoyu kabul et (New_Value) yap
. . .
son
Bir kabul bir ile maddesini zaman fıkra açık veya kapalı olduğunu. Boole ise
ifadesi ne zaman maddesi olduğunu, şu anda doğrudur kabul koşulu denir
açık ; Boole ifadesi yanlışsa, kabul cümlesine kapalı denir .
Koruması olmayan bir kabul maddesi her zaman açıktır. Açık bir kabul
madde randevu için kullanılabilir; kapalı bir kabul maddesi buluşma olamaz.
Bir seçme yan tümcesinde birkaç korumalı kabul tümcesi olduğunu varsayalım .
Böyle bir seçme yan tümcesi genellikle sonsuz bir döngüye yerleştirilir. Döngü neden olur
seçme maddesi her biri, sürekli olarak çalıştırılması gereken zaman maddesi değerlendirildi
her tekrarda. Her tekrar, açık kabul cümleciklerinin bir listesinin oluşturulmasına neden olur .
inşa edilmiştir. Açık tümcelerden tam olarak biri boş olmayan bir kuyruğa sahipse, bir
o kuyruktan adaçayı alınır ve bir buluşma gerçekleşir. birden fazla ise
açık kabul cümleciklerinin boş olmayan kuyrukları var, bir kuyruk olmayan seçilmiş
deterministik olarak, o kuyruktan bir mesaj alınır ve bir randevu alınır.
yer. Tüm açık yan tümcelerin kuyrukları boşsa, görev bir ileti bekler.
Bu kabul maddelerinden birine varmak, o zaman bir randevu gerçekleşecek. Eğer
bir seçim yürütülür ve her kabul maddesi kapatılır, bir çalışma zamanı istisnası
veya hata sonuçları. Bu olasılık, aşağıdakilerden birinin yapıldığından emin olarak önlenebilir.
zaman hükümler her zaman doğru ya da eklemektir başka yer maddesini seçin . Bir
else yan tümcesi, kabul tümcesi dışında herhangi bir ifade dizisini içerebilir .
Bir select yan tümcesi , seçilen sonlanan özel bir ifadeye sahip olabilir.
yalnızca açık olduğunda ve başka bir kabul maddesi açık olmadığında. Bir sonlandırma maddesi,
seçildiğinde, görevin işiyle bittiği ancak henüz sonlandırılmadığı anlamına gelir.
uluslu. Görev sonlandırma bu bölümde daha sonra tartışılacaktır.
13.6.3 Yarışma Senkronizasyonu
Şimdiye kadar açıklanan özellikler, işbirliği senkronizasyonu sağlar ve
görevler arası iletişim. Ardından, karşılıklı olarak özel erişimin nasıl
Ada'da paylaşılan veri yapılarına zorlanabilir.
Bir veri yapısına erişim bir görev tarafından kontrol edilecekse, karşılıklı olarak
özel erişim, bir görev içindeki veri yapısını bildirerek elde edilebilir.
Görev yürütmenin semantiği, genellikle birbirini dışlayan erişimi garanti eder.
yapıya, çünkü görevdeki yalnızca bir kabul cümlesi bir anda aktif olabilir.
verilen zaman. Bunun tek istisnası, görevler süreç içinde yuvalandığında ortaya çıkar.
süreler veya diğer görevler. Örneğin, paylaşılan bir veri yapısını tanımlayan bir görev
iç içe bir göreve sahipse, bu iç içe görev, paylaşılan yapıya da erişebilir.

Sayfa 621
600
Bölüm 13 Eşzamanlılık
verilerin bütünlüğünü bozabilir. Böylece, kontrol edilmesi amaçlanan görevler
paylaşılan bir veri yapısına erişim, görevleri tanımlamamalıdır.
Aşağıdakiler, aşağıdakiler için bir monitör uygulayan bir Ada görevi örneğidir:
Bir tampon. Tampon, Bölüm 13.3'teki arabellek gibi davranır;
senkronizasyon semaforlarla kontrol edilir.
görev Buf_Task (şimdiki değeri)
entry Deposit (Madde: in Integer);
entry (: Ürün Getirme dışarı Integer);
son Buf_Task;
Görev içeriğinin Buf_Task olduğunu
Bufsize : sabit Tamsayı := 100;
Tampon: dizi (1..Bufsize) arasında bir tamsayı;
Doldurulmuş : Tamsayı aralığı 0..Bufsize := 0;
Sonraki_In,
Next_Out : Tamsayı aralığı 1..Bufsize := 1;
başlamak
döngü
Seçme
ne zaman Dolgulu <BUFSIZE =>
kabul : Mevduat (Öğe içinde Integer) do
Buf(Next_In) := Öğe;
Son Mevduat;
Next_In := (Next_In mod Bufsize) + 1;
Dolu := Dolu + 1;
veya
zaman dolu> 0 =>
kabul : (Madde Getirme dışarı Integer) do
Öğe := Buf(Sonraki_Çıkış);
son Getir;
Next_Out := (Next_Out mod Bufsize) + 1;
Dolu := Dolu - 1;
son seçim ;
son döngü ;
son Buf_Task;
Bu örnekte, her iki kabul cümlesi de genişletilmiştir. Bu genişletilmiş maddeler
ilişkili kabul tümceleri olarak adlandırılan görevlerle eşzamanlı olarak yürütülebilir .
Bir yapımcı ve kullanabileceği bir tüketici için görevler Buf_Task var
aşağıdaki form:
görev Yapımcı;
görev Tüketici;
Görev içeriğinin Yapımcı olduğunu
New_Value : Tamsayı;
başlamak

Sayfa 622
13.6 Eşzamanlılık 601 için Ada Desteği
döngü
-- New_Value üret --
Buf_Task.Deposit(Yeni_Değer);
son döngü ;
son Yapımcı;
Görev içeriğinin Tüketici olduğunu
Stored_Value : Tamsayı;
başlamak
döngü
Buf_Task.Fetch(Stored_Value);
-- Stored_Value tüket --
son döngü ;
son Tüketici;
13.6.4 Görev Sonlandırma
Kontrol, kodunun sonuna ulaştıysa, bir görevin yürütülmesi tamamlanır .
gövde. Bu, bir istisna oluşturulduğu için oluşabilir.
işleyici yok. Ada istisna işleme Bölüm 14'te açıklanmıştır.
bağımlılar adı verilen başka görevler oluşturuldu , yürütüldüğünde sonlandırılır
tamamlandı. Bağımlı görevler oluşturan bir görev, aşağıdaki durumlarda sonlandırılır:
kodunun yürütülmesi tamamlandı ve tüm bağımlıları sonlandırıldı. A
görev, açık bir sonlandırma yan tümcesinde bekleyerek yürütülmesini sonlandırabilir . Bunda
durumda, görev yalnızca ana (blok, alt program veya
onu oluşturan görev) ve bu master'a bağlı olan tüm görevler ya
tamamlandı veya açık bir sonlandırma maddesinde bekliyorlar . Bu durumda, tüm bunlar
görevler aynı anda sonlandırılır. kadar bir blok veya alt programdan çıkılmaz.
tüm bağımlı görevleri sonlandırılır.
13.6.5 Öncelikler
Bir göreve, spesifikasyonunda bir öncelik atanabilir. Bu bir pragma ile yapılır, 3
de olduğu gibi
pragma Önceliği( statik ifade );
Statik ifade genellikle ya bir tamsayı değişmezidir ya da önceden tanımlanmış bir
stant. İfadenin değeri, görev için göreli önceliği belirtir veya
göründüğü görev türü tanımı. Olası öncelik değerleri aralığı:
uygulamaya bağlı. Mümkün olan en yüksek öncelik ile belirtilebilir
Son özellik, öncelik tanımlanan tip, System ( Sistem
önceden tanımlanmış bir pakettir). Örneğin, aşağıdaki satır en yüksek değeri belirtir.
herhangi bir uygulamada öncelik:
pragma Priority(System.Priority'Last);
3. Pragmanın derleyici için bir talimat olduğunu hatırlayın.

Sayfa 623
602
Bölüm 13 Eşzamanlılık
Görevlere öncelikler atandığında, bu öncelikler görev tarafından kullanılır.
göreve hazır kuyruğundan hangi görevin seçileceğini belirlemek için zamanlayıcı
şu anda yürütülmekte olan görev ya engellendi, tahsis edilen görevin sonuna ulaştı
veya yürütmesini tamamlar. Ayrıca, daha yüksek önceliğe sahip bir görev
o anda yürütülmekte olan görevden daha fazla görev hazır kuyruğuna girer, daha düşük
yürütülmekte olan öncelikli görev önceliklidir ve daha yüksek öncelikli görev başlar
yürütülmesi (veya daha önce yürütülüyorsa yürütmeye devam etmesi).
Önceden alınan bir görev, işlemciyi kaybeder ve göreve hazır kuyruğuna yerleştirilir.
13.6.6 Korunan Nesneler
Gördüğümüz gibi, paylaşılan verilere erişim, verileri içine alarak kontrol edilebilir.
bir görevde ve yalnızca dolaylı olarak sağlayan görev girişleri aracılığıyla erişime izin verilmesi
rekabet senkronizasyonu. Bu yöntemle ilgili bir sorun, farklı olmasıdır.
Randevu mekanizmasını verimli bir şekilde uygulamak için hayali. Ada 95 korumalı
nesneler, rekabet senkronizasyonu sağlamak için alternatif bir yöntem sağlar.
Randevu mekanizmasını içermesi gerekmeyen
Korunan bir nesne bir görev değildir; bölümünde açıklandığı gibi daha çok bir monitör gibidir.
Bölüm 13.4. Korunan nesnelere, korumalı alt programlardan biri ile erişilebilir.
gram veya görevlerdeki kabul cümleciklerine sözdizimsel olarak benzer girdilerle . 4
Korumalı alt programlar, aşağıdakileri sağlayan korumalı prosedürler olabilir:
korunan nesnenin verilerine karşılıklı olarak özel okuma-yazma erişimi veya
bu verilere eşzamanlı salt okunur erişim sağlayan korumalı işlevler.
Girişler, korumalara sahip olabilmeleri bakımından korumalı alt programlardan farklıdır.
Korunan bir prosedürün gövdesi içinde, şu andaki örneği,
korunan birimi çevreleyen bir değişken olarak tanımlanır; bir pro-
Tespit edilen fonksiyon, çevreleyen korumalı birimin mevcut örneği tanımlanır
eşzamanlı salt okunur erişime izin veren bir sabit olmak.
Korunan bir nesneye yapılan giriş çağrıları, aşağıdakilerle eşzamanlı iletişim sağlar:
aynı korumalı nesneyi kullanan bir veya daha fazla görev. Bu giriş çağrıları
bir görevde bulunan verilere sağlanana benzer erişim.
Önceki alt bölümdeki bir görevle çözülen arabellek sorunu
korunan bir nesne ile daha basit bir şekilde çözülebilir. Bu örneğin yaptığına dikkat edin
korumalı alt programları içermez.
korumalı tampon olduğu
entry Deposit (Madde: in Integer);
entry (: Ürün Getirme dışarı Integer);
özel
Bufsize : sabit Tamsayı := 100;
Tampon: dizi (1..Bufsize) arasında bir tamsayı;
Doldurulmuş : Tamsayı aralığı 0..Bufsize := 0;
4. Korunan nesne gövdelerindeki girişler, kabul yerine ayrılmış sözcük girişini kullanır.
görev organlarında kullanılır.

Sayfa 624
13.7 Java Konuları 603
Sonraki_In,
Next_Out : Tamsayı aralığı 1..Bufsize := 1;
son Tampon;
korumalı gövde Tampon olduğu
entry Deposit (Madde: in Integer)
ne zaman Dolgulu <BUFSIZE olduğunu
başlamak
Buf(Next_In) := Öğe;
Next_In := (Next_In mod Bufsize) + 1;
Dolu := Dolu + 1;
Son Mevduat;
entry : (Madde Getirme dışarı Integer) ne zaman Dolgulu> 0 olduğu
başlamak
Öğe := Buf(Sonraki_Çıkış);
Next_Out := (Next_Out mod Bufsize) + 1;
Dolu := Dolu - 1;
son Getir;
son Tampon;
13.6.7 Değerlendirme
Monitörler oluşturmak için genel mesaj ileten eşzamanlılık modelini kullanma
soyut veri türlerini desteklemek için Ada paketlerini kullanmak gibidir; her ikisi de
gerekenden daha geneldir. Korumalı nesneler sağlamak için daha iyi bir yoldur
paylaşılan verilere senkronize erişim.
Bağımsız belleklere sahip dağıtılmış işlemcilerin yokluğunda,
uygulama aracı olarak mesaj geçişi ile monitörler ve görevler arasında seçim
eşzamanlı bir ortamda paylaşılan verilere senkronize erişimden bahsetmek
biraz zevk meselesi. Ancak Ada durumunda, korunan nesneler
paylaşılan verilere eşzamanlı erişimi destekleme görevlerinden açıkça daha iyi. Değil
sadece kod daha basittir; aynı zamanda çok daha verimlidir.
Dağıtılmış sistemler için mesaj geçişi, eşzamanlılık için daha iyi bir modeldir.
çünkü doğal olarak yürütülen ayrı süreçler kavramını destekler.
Ayrı işlemcilerde paralel.
13.7 Java Konuları
Java'daki eşzamanlı birimler , kodu içinde olabilen run adlı yöntemlerdir .
diğer bu tür yöntemlerle (diğer nesnelerin) eşzamanlı yürütmesi ve
ana yöntem. Çalıştırma yöntemlerinin yürütüldüğü sürece denir.
iplik . Java'nın iş parçacıkları hafif görevlerdir; bu, hepsinin içinde çalıştığı anlamına gelir.
aynı adres alanı. Bu, ağır olan Ada görevlerinden farklıdır.

Sayfa 625
604
Bölüm 13 Eşzamanlılık
iş parçacıkları (kendi adres alanlarında çalışırlar). 5 Bunun önemli bir sonucu
fark, iş parçacıklarının Ada'nın görevlerinden çok daha az ek yük gerektirmesidir.
Run yöntemiyle bir sınıfı tanımlamanın iki yolu vardır . Bunlardan biri
önceden tanımlanmış Thread sınıfının bir alt sınıfını tanımlamak ve çalışmasını geçersiz kılmaktır.
yöntem. Ancak, yeni alt sınıfın gerekli bir doğal ebeveyni varsa, o zaman
bir alt sınıfı olarak tanımlayarak Konu besbelli çalışmaz. Bu durumlarda,
doğal ebeveyninden miras alan ve aşağıdakileri uygulayan bir alt sınıf tanımlarız.
Çalıştırılabilir arayüz. Runnable , çalıştırma yöntemi protokolünü sağlar, bu nedenle herhangi bir
Runnable'ı uygulayan sınıf, run öğesini tanımlamalıdır . Bu sınıfın bir nesnesi
Uygulamalar Runnable , Thread yapıcısına iletilir . Yani bu yaklaşım
Bölüm 13.7.5'teki örnekte görüleceği gibi, hala bir Thread nesnesi gerektirir .
Ada'da görevler aktörler veya sunucular olabilir ve görevler birbirleriyle iletişim kurar.
kabul cümleleri aracılığıyla birbirlerine . Java çalıştırma yöntemlerinin tümü aktörlerdir ve orada
birleştirme dışında birbirleriyle iletişim kurmaları için hiçbir mekanizma yoktur.
yöntemi (bkz. Bölüm 13.7.1) ve paylaşılan veriler aracılığıyla.
Java dizileri karmaşık bir konudur; bu bölüm yalnızca bir giriş sağlar
en basit ama en kullanışlı kısımlarına.
13.7.1 İplik Sınıfı
Konu sınıfa herhangi bir başka sınıfların doğal ebeveyn değildir. sağlar
alt sınıfları için bazı hizmetler, ancak bunlarla doğal bir şekilde ilişkili değildir.
hesaplama amaçlı. İş parçacığı , eşzamanlılık oluşturmak için kullanılabilen tek sınıftır.
Java programları kiralayın. Daha önce belirtildiği gibi, Bölüm 13.7.5, aşağıdakileri kısaca tartışacaktır:
kullanımı Runnable arayüz.
Konu sınıf beş Kurucular ve yöntemler topluluğu içerir
ve sabitler. İş parçacığının eylemlerini açıklayan run yöntemi,
her zaman Thread alt sınıfları tarafından geçersiz kılınır . Başlangıç yöntemi Konu
run yöntemini çağırarak iş parçacığını eşzamanlı bir birim olarak başlatır . 6 Çağrı
start olağandışıdır, çünkü kontrol hemen arayana geri döner ve ardından
yeni başlatılan çalıştırma yöntemine paralel olarak yürütmesine devam eder .
Bir iskelet alt sınıf aşağıda Konu ve yaratan bir kod parçası
alt sınıfın bir nesnesidir ve yeni iş parçacığında run yönteminin yürütülmesini başlatır :
class MyThread , Thread'i genişletir {
public void run() { . . . }
}
. . .
Konu myTh = new MyThread();
myTh.start();
5. Aslında Ada görevleri ağır işlermiş gibi davransa da, bazı durumlarda
şimdi iş parçacığı olarak uygulandı. Bu bazen IBM Ratio- gibi kitaplıklar kullanılarak yapılır.
nal Apex Yerel POSIX İş Parçacığı Kitaplığı.
6. Çalıştırma yöntemini doğrudan çağırmak her zaman işe yaramaz, çünkü başlatma biraz-
gerekli süreler başlatma yöntemine dahildir.

Sayfa 626
13.7 Java Konuları 605
Bir Java uygulama programı yürütmeye başladığında, yeni bir iş parçacığı oluşturulur
( ana yöntemin çalışacağı yer) ve ana çağrılır. Bu nedenle, tüm Java
uygulama programları iş parçacıklarında çalışır.
Bir program birden çok iş parçacığına sahip olduğunda, bir zamanlayıcı hangisini belirlemelidir?
iş parçacığı veya iş parçacıkları herhangi bir zamanda çalışacaktır. Çoğu durumda, yalnızca tek bir
işlemci kullanılabilir, bu nedenle bir seferde yalnızca bir iş parçacığı çalışır. zor
Java zamanlayıcısının nasıl çalıştığına dair kesin bir açıklama verin, çünkü farklı
ent uygulamaları (Solaris, Windows vb.)
iplikler tam olarak aynı şekilde. Bununla birlikte, tipik olarak, zamanlayıcı eşit verir-
tümünü varsayarak, her bir hazır iş parçacığına zaman dilimlerini yuvarlak robin tarzında boyutlandırın.
bu iş parçacıkları aynı önceliğe sahiptir. Bölüm 13.7.2 ne kadar farklı olduğunu açıklar.
öncelikler farklı iş parçacıklarına verilebilir.
Konu sınıf gerçekleştirilmesini kontrol etmek için çeşitli yöntemler sunar
iş parçacığı Verim herhangi bir parametre alır yöntem olup, bir taleptir
işlemciyi gönüllü olarak teslim etmek için çalışan iş parçacığı. 7 İplik konur
hemen göreve hazır kuyruğunda, çalışmaya hazır hale getirir. zamanlayıcı
sonra göreve hazır kuyruğundan en yüksek öncelikli iş parçacığını seçer. eğer varsa
az önce verilenden daha yüksek önceliğe sahip başka hazır iş parçacığı yok
işlemci, işlemciyi almak için bir sonraki iş parçacığı da olabilir.
Uyku yöntemi tam sayı olan tek bir parametre, yer alır
uykuyu arayanın iş parçacığının engellenmesini istediği milisaniye . Sonrasında
belirtilen milisaniye sayısı geçti, iş parçacığı konulacak
göreve hazır kuyruk. Çünkü bir iş parçacığının ne kadar süreceğini bilmenin bir yolu yok
çalışmadan önce göreve hazır kuyruğunda, uyku parametresi minimumdur
zamanın miktarı iplik olacak değil yürütme olmak. Uyku yöntemi kutu
yöntemde işlenmesi gereken bir InterruptedException atın
uyku denilen şeydir . İstisnalar Bölüm 14'te ayrıntılı olarak açıklanmaktadır.
Birleştirme yöntemi kadar yürütme geciktirmek için bir yöntem sağlamak için kullanılır
Çalışma başka bir iş parçacığı gibi bir yöntem, yürütme tamamlamıştır. birleştirme kullanılır
Bir yöntemin işlenmesi diğerinin çalışmasına kadar devam edemediğinde
iplik tamamlandı. Örneğin, aşağıdaki çalıştırma yöntemine sahip olabiliriz :
public void run() {
. . .
Konu myTh = yeni Konu();
myTh.start();
// bu iş parçacığının hesaplanmasının bir kısmını yap
myTh.join(); // myTh'nin tamamlanmasını bekleyin
// bu iş parçacığının geri kalanını yap
}
Birleştirme yöntemi koyar bloke halde, kutu içinde aramaları iplik
yalnızca birleştirmenin çağrıldığı iş parçacığının tamamlanmasıyla sonlandırılabilir .
Bu iş parçacığı engellenirse, kilitlenme olasılığı vardır. İle
7. Getiri yöntemi aslında planlayıcıya bir "öneri" olarak tanımlanır.
veya takip etmeyebilir (genelde olsa da).

Sayfa 627
606
Bölüm 13 Eşzamanlılık
Bunu önlemek için, birleştirme , zaman sınırı olan bir parametre ile çağrılabilir.
çağıran iş parçacığının çağrılan iş parçacığı için ne kadar bekleyeceğinin milisaniyesi
tamamlayınız. Örneğin,
myTh.join(2000);
çağıran iş parçacığının myTh'nin tamamlanması için iki saniye beklemesine neden olur . eğer varsa
iki saniye geçtikten sonra yürütmesini tamamlamadı, çağıran iş parçacığı
hazır kuyruğa geri konur, bu da yürütmeye devam edeceği anlamına gelir
planlandığı anda.
Java'nın ilk sürümleri üç tane daha Thread yöntemini içeriyordu : stop ,
askıya alın ve devam ettirin . Bunların üçü de kullanımdan kaldırıldı çünkü
güvenlik sorunları. Durdurma yöntemi bazen basit ile geçersiz kılınır
referans değişkenini null olarak ayarlayarak iş parçacığını yok eden yöntem .
Bir çalıştırma yönteminin yürütmesini sonlandırmasının normal yolu , işlemin sonuna ulaşmaktır.
onun kodu. Bununla birlikte, birçok durumda, iş parçacıkları sonlandırması söylenene kadar çalışır. Saygı-
Bunu yaparken, bir iş parçacığının olması gerekip gerekmediğini nasıl belirleyebileceği sorusu var.
devam et veya bitir. Kesme yöntemi a ile iletişim kurmak için bir yöntemdir
durması gereken iş parçacığı. Bu yöntem iş parçacığını durdurmaz; daha doğrusu gönderir
iş parçacığı, iş parçacığı nesnesinde aslında sadece bir bit ayarlayan bir mesajdır;
iş parçacığı tarafından kontrol edilebilir. Bit, yüklem yöntemiyle kontrol edilir,
kesintiye uğradı . Bu tam bir çözüm değil, çünkü iş parçacığı bir
kesme girişiminde uyku veya zamanda bekliyor olabilir kesme
yöntem çağrılır, bu da yapılıp yapılmadığını kontrol etmeyeceği anlamına gelir.
kesintiye uğradı. Bu durumlar için, kesme yöntemi ayrıca bir istisna atar.
siyon, InterruptedException da gelen (uyanmaya parçacığı neden olur,
uyumak veya beklemek). Böylece, bir iş parçacığı, sahip olup olmadığını görmek için periyodik olarak kontrol edebilir.
kesintiye uğrayıp uğramadığı ve kesilip kesilmeyeceği. İplik kaçıramaz
kesinti, çünkü kesinti meydana geldiğinde uykudaysa veya bekliyorsa,
kesinti ile uyandırılacaktır. Aslında, eylemlerle ilgili daha fazla ayrıntı var
ve kesme kullanımları , ancak burada ele alınmamıştır (Arnold ve diğerleri, 2006).
13.7.2 Öncelikler
Konuların önceliklerinin hepsinin aynı olması gerekmez. Bir iş parçacığının varsayılan önceliği
başlangıçta onu oluşturan iş parçacığı ile aynıdır. Eğer ana bir iş parçacığı oluşturur, onun
varsayılan öncelik sabittir NORM_PRIORITY genellikle 5. olduğunu Konu
diğer iki öncelik sabitini tanımlar, MAX_PRIORITY ve MIN_PRIORITY ,
değerleri genellikle sırasıyla 10 ve 1'dir. 8 Bir iş parçacığının önceliği
setPriority yöntemiyle değiştirilebilir . Yeni öncelik herhangi biri olabilir
önceden tanımlanmış sabitler veya MIN_PRIORITY ile arasındaki herhangi bir sayı
MAX_PRIORITY . Getpriority yöntemi a'nın mevcut öncelik döndürür
iplik. Öncelik sabitleri Thread içinde tanımlanır .
8. Öncelik sayısı uygulamaya bağlıdır, dolayısıyla daha az veya daha fazla öncelik olabilir.
Bazı uygulamalarda 10 seviye.

Sayfa 628
13.7 Java Konuları 607
Farklı önceliklere sahip iş parçacıkları olduğunda, zamanlayıcının davranışı
veya bu öncelikler tarafından kontrol edilir. Yürütülen iş parçacığı engellendiğinde veya
öldürülür veya bunun için zaman dilimi sona ererse, zamanlayıcı iş parçacığını içinden seçer.
en yüksek önceliğe sahip göreve hazır kuyruk. Daha düşük önceliğe sahip bir iş parçacığı
yalnızca daha yüksek önceliğe sahip biri göreve hazır kuyruğunda değilse çalışır.
fırsat doğar.
13.7.3 Semaforlar
Java.util.concurrent.Semaphore paketi tanımlayan Sema-
fore sınıfı. Bu sınıfın nesneleri sayma semaforlarını uygular. bir sayı-
ing semaforunun bir sayacı vardır, ancak iş parçacığı tanımlayıcılarını depolamak için sıra yoktur. bu
Semaphore sınıfı, edinme ve bırakma olmak üzere iki yöntem tanımlar.
Bölüm 13.3'te açıklanan bekleme ve bırakma işlemlerine yanıt verin .
Semaphore için temel kurucu bir tamsayı parametresi alır;
semaforun sayacını başlatır. Örneğin, aşağıdakiler için kullanılabilir
başlatmak fullspots ve emptyspots tampon, örneğin semaforları
Bölüm 13.3.2:
tam noktalar = yeni Semafor (0);
boş noktalar = yeni Semafor(BUFLEN);
Üretici yönteminin para yatırma işlemi aşağıdaki gibi görünecektir:
boş noktalar.acquire();
mevduat(değer);
fullspots.release();
Benzer şekilde, tüketici yönteminin getirme işlemi aşağıdaki gibi görünecektir:
fullspots.acquire();
getir(değer);
emptyspots.release();
Para yatırma ve getirme yöntemleri, Bölüm 13.7.4'te kullanılan yaklaşımı kullanabilir.
tampona erişimler için gerekli olan rekabet senkronizasyonunu sağlamak.
13.7.4 Yarışma Senkronizasyonu
Java yöntemleri (ancak yapıcılar değil) senkronize edilecek şekilde belirtilebilir . A
belirli bir nesne aracılığıyla çağrılan senkronize yöntemin yürütülmesini tamamlaması gerekir.
Bu nesne üzerinde başka herhangi bir eşitlenmiş yöntemin çalışabilmesinden önce. Yarışma
bir nesne üzerinde senkronizasyon, yöntemlerin
paylaşılan verilere erişim senkronize edilir. Senkronize mekanizma,
aşağıdaki gibi uygulanır: Her Java nesnesinin bir kilidi vardır. Senkronize yöntemler
yürütülmesine izin verilmeden önce nesnenin kilidini almaları gerekir;

Sayfa 629
608
Bölüm 13 Eşzamanlılık
bu sırada diğer senkronize yöntemlerin nesne üzerinde yürütülmesini engeller.
zaman. Senkronize bir yöntem, üzerinde çalıştığı nesne üzerindeki kilidi serbest bırakır.
yürütmesini tamamladığında, bu tamamlama bir istisnadan kaynaklansa bile.
Aşağıdaki iskelet sınıfı tanımını göz önünde bulundurun:
sınıf ManageBuf {
özel int [100] buf;
. . .
genel senkronize geçersiz mevduat( int item) { . . . }
genel senkronize int fetch() { . . . }
. . .
}
ManageBuf'ta tanımlanan iki yöntemin her ikisi de şu şekilde tanımlanmıştır:
senkronize , bu da birbirlerine müdahale etmelerini önler.
ayrı iş parçacıkları tarafından çağrıldıklarında aynı nesne üzerinde yürütülür.
Yöntemlerinin tümü senkronize olan bir nesne, etkin bir şekilde bir monitördür.
Bir nesnenin bir veya daha fazla eşitlenmiş yönteminin yanı sıra
bir veya daha fazla senkronize olmayan yöntem. Senkronize edilmemiş bir yöntem çalışabilir
Senkronize bir yöntemin yürütülmesi sırasında bile herhangi bir zamanda bir nesne üzerinde.
Bazı durumlarda, paylaşılan verilerle ilgilenen ifadelerin sayısı
yapı, yöntemdeki diğer ifadelerin sayısından önemli ölçüde azdır
hangisinde bulunur. Bu durumlarda, kod segmentini senkronize etmek daha iyidir.
Bu, tüm yöntem yerine paylaşılan veri yapısını değiştirir. Bu
genel formu şu şekilde olan sözde senkronize bir ifade ile yapılabilir.
senkronize ( ifade ){
ifadeler
}
ifadenin bir nesne olarak değerlendirilmesi gerektiği ve ifadenin bir
tek deyim veya bileşik deyim. Nesne yürütme sırasında kilitlenir.
deyimin ya da bileşik deyimin tion, bu nedenle deyim ya da bileşik
deyim, tam olarak senkronize bir yöntemin gövdesiymiş gibi yürütülür.
Kendisi için tanımlanmış senkronize yöntemleri olan bir nesnenin bir kuyruğu olmalıdır.
onunla ilişkili olan, denemiş olan senkronize yöntemleri saklayan
başka bir senkronize yöntemle çalıştırılırken üzerinde yürütün.
Aslında, her nesnenin içsel koşul sırası adı verilen bir kuyruğu vardır . Bunlar
sıralar dolaylı olarak sağlanır. Senkronize bir yöntem tamamlandığında
bir nesne üzerinde yürütme, nesnenin içsel koşulunda bekleyen bir yöntem.
tion kuyruğu, eğer böyle bir yöntem varsa, göreve hazır kuyruğa alınır.
13.7.5 İşbirliği Senkronizasyonu
Java'da işbirliği senkronizasyonu, bekle , bildir ,
ve tümü kök sınıf olan Object içinde tanımlanan notifyAll yöntemleri
tüm Java sınıflarının Object dışındaki tüm sınıflar bu yöntemleri devralır. Her

Sayfa 630
13.7 Java Konuları 609
Nesne çağrıda parçacığı tümünün bir bekleme listesi vardır bekleme nesne üzerinde.
Bildirmek yöntem tek bekleyen iş parçacığı söylemek denir, öyle bir olay
bekleyen meydana gelmiş olabilir. Uyandırılan belirli iş parçacığı
tarafından haberdar Java Virtual Machine çünkü (JVM), tespit edilemeyen
iş parçacığı nesnesinin bekleme listesinden rastgele birini seçer. çünkü
bu, bekleyen iş parçacıklarının farklı şekilde bekliyor olabileceği gerçeğiyle birlikte
koşullarda, notify yerine genellikle notifyAll yöntemi kullanılır . bu
notifyAll yöntemi, nesnenin bekleme listesindeki tüm iş parçacıklarını put-
onları göreve hazır kuyruğunda ting.
wait , notify ve notifyAll yöntemleri yalnızca şuradan çağrılabilir:
tarafından bir nesneye yerleştirilen kilidi kullandıkları için senkronize bir yöntem içinde
böyle bir yöntem. Bekleme çağrısı her zaman kontrol edilen bir süre döngüsüne konur.
yöntemin beklediği koşula göre. Süre döngüsü gerekli olan
çünkü iş parçacığını uyandıran bildir veya bildir
ipliğin neden olduğu durumdan farklı bir koşuldaki değişiklik nedeniyle çağrılır.
bekliyordu. NotifyAll için yapılan bir çağrıysa , daha da küçük bir şans vardır:
Beklenen koşul artık doğru. notifyAll kullanımı nedeniyle , bazıları
diğer iş parçacığı, son test edildiğinden beri koşulu yanlış olarak değiştirmiş olabilir.
Bekleme yöntemi atabilir InterruptedException hangi bir olduğu,
arasında soyundan özel durum . Java'nın istisna işlemesi Bölüm'de tartışılmaktadır
14. Bu nedenle, wait çağıran herhangi bir kod aynı zamanda InterruptedExcep'i de yakalamalıdır.
tion . Beklenen koşulun theCondition olarak adlandırıldığını varsayarsak ,
beklemeyi kullanmanın geleneksel yolu aşağıdaki gibidir:
denemek {
while (!Koşul)
Bekle();
-- Koşul gerçekleştikten sonra ne gerekiyorsa yapın
}
catch (InterruptedException myProblem) { . . . }
Aşağıdaki program, int değerini depolamak için dairesel bir kuyruk uygular.
ues. Hem işbirliğini hem de rekabet senkronizasyonunu gösterir.
// Sıra
// Bu sınıf, int'yi depolamak için dairesel bir sıra uygular
// değerler. Tahsis etmek için bir kurucu içerir ve
// kuyruğu belirtilen bir boyuta başlatıyoruz. sahip
// değerleri eklemek için senkronize yöntemler ve
// kuyruktan değerler kaldırılıyor.
sınıf Kuyruk {
özel int [] sıra;
özel int sonrakiIn,
sonrakiÇıkış,
dolu,
queSize;

Sayfa 631
610
Bölüm 13 Eşzamanlılık
public Queue( int size) {
que = yeni int [boyut];
dolu = 0;
sonrakiIn = 1;
sonrakiÇıkış = 1;
queSize = boyut;
} //** Kuyruk yapıcısının sonu
genel senkronize geçersiz mevduat ( int öğesi)
atar InterruptedException {
denemek {
while (dolu == queSize)
Bekle();
que [nextIn] = öğe;
nextIn = (nextIn % queSize) + 1;
doldurulmuş++;
notifyAll();
} //** try yan tümcesinin sonu
yakalamak (InterruptedException e) {}
} //** para yatırma yönteminin sonu
ortak senkronize int getirme()
atar InterruptedException {
int öğe = 0;
denemek {
while (dolu == 0)
Bekle();
item = que [nextOut];
nextOut = (nextOut % queSize) + 1;
doldurulmuş--;
notifyAll();
} //** try yan tümcesinin sonu
yakalamak (InterruptedException e) {}
iade öğesi;
} //** getirme yönteminin sonu
} //** Queue sınıfının sonu
İstisna işleyicisinin ( catch ) burada hiçbir şey yapmadığına dikkat edin .
Sırayı kullanabilecek üretici ve tüketici nesnelerini tanımlayan sınıflar
sınıf aşağıdaki gibi tanımlanabilir:
class Yapımcı İş parçacığını genişletir {
özel Kuyruk arabelleği;
public Producer(Queue que) {
arabellek = sıra;
}
public void run() {

Sayfa 632
13.7 Java Konuları 611
int yeni _item;
while (doğru) {
//-- Bir new_item oluştur
tampon.deposit(yeni_item);
}
}
}
class Tüketici Konuyu genişletir {
özel Kuyruk arabelleği;
public Tüketici(Kuyruk kuyruğu) {
arabellek = sıra;
}
public void run() {
int depolanan_öğe;
while (doğru) {
store_item = buffer.fetch();
//-- depolanan_öğeyi tüket
}
}
}
Aşağıdaki kod bir Queue nesnesi ve bir Producer ve bir Con-
sumer nesnesi, her ikisi de Queue nesnesine eklenir ve yürütmeye başlar:
Kuyruk buff1 = yeni Kuyruk(100);
Üretici üretici1 = yeni Üretici(buff1);
Tüketici tüketici1 = yeni Tüketici(buff1);
yapımcı1.start();
tüketici1.start();
Üretici ve Tüketiciden birini veya her ikisini de uygulama olarak tanımlayabiliriz.
ait mentations Runnable arayüzü yerine olarak alt sınıfları Konu .
Tek fark, şimdi olarak görünecek olan ilk satırdadır.
class Producer, Runnable { öğesini uygular . . . }
Böyle bir sınıfın bir nesnesini yaratmak ve çalıştırmak için, yine de bir
Nesneye bağlı iş parçacığı nesnesi. Bu, aşağıdaki şekilde gösterilmiştir.
alçaltma kodu:
Üretici üretici1 = yeni Üretici(buff1);
Thread üreticisiThread = new Thread(producer1);
yapımcıThread.start();
Tampon nesnesinin Producer yapıcısına iletildiğini ve
Üreticiler nesnesi, Thread yapıcısına iletilir .

Sayfa 633
612
Bölüm 13 Eşzamanlılık
13.7.6 Engellemeyen Senkronizasyon
Java, belirli değişkenlere erişimi kontrol etmek için bazı sınıflar içerir.
engelleme veya beklemeyi içermez. java.util.concurrent.atomic
paket, belirli engellemesiz senkronize erişime izin veren sınıfları tanımlar.
int , long ve boolean ilkel tür değişkenlerinin yanı sıra referanslar ve
diziler. Örneğin, AtomicInteger sınıfı, alıcı ve ayarlayıcı yöntemlerini tanımlar.
ods ve ayrıca toplama, artırma ve eksiltme işlemleri için yöntemler. Bunlar
işlemlerin tümü atomiktir; yani, kesintiye uğramazlar, bu nedenle kilitler
etkilenen değişkenlerin değerlerinin bütünlüğünü garanti etmek için gerekli
çok iş parçacıklı program. Bu, hassas bir senkronizasyondur—sadece tek bir
değişken. Artık çoğu makinede bu işlemler için atomik talimatlar var.
int ve long türleri, bu nedenle genellikle uygulanması kolaydır (örtük kilitler
gerekli değil).
Engellemeyen senkronizasyonun avantajı verimliliktir. Engelsiz bir
çekişme sırasında gerçekleşmeyen erişim daha yavaş olmayacak ve genellikle
senkronize kullanandan daha hızlı . Gerçekleşen engellemesiz bir erişim
çekişme sırasında kesinlikle senkronize kullanandan daha hızlı olacaktır ,
çünkü ikincisi, iş parçacığının askıya alınmasını ve yeniden planlanmasını gerektirecektir.
13.7.7 Açık Kilitler
Java 5.0, senkronize yönteme alternatif olarak açık kilitleri tanıttı
ve örtük kilitler sağlayan bloklar. Kilit arayüzü beyan
lock , unlock ve tryLock yöntemlerini kullanın. Önceden tanımlanmış ReentrantLock sınıfı
Kilit arayüzünü uygular . Bir kod bloğunu kilitlemek için aşağıdaki deyim
kullanılabilir:
Kilit kilidi = yeni ReentrantLock();
. . .
kilit.kilit();
denemek {
// Paylaşılan verilere erişen kod
} nihayet {
Lock.unlock();
}
Bu iskelet kodu, bir Lock nesnesi oluşturur ve üzerindeki kilit yöntemini çağırır .
Nesneyi kilitle . Ardından, kritik kodu içine almak için bir try bloğu kullanır . çağrı
kilit açma , kilidin serbest bırakılmasını garanti etmek için bir nihayet yan tümcesindedir, ne olursa olsun
try bloğunda ne olur .
Bunun yerine açık kilitlerin kullanıldığı en az iki durum vardır.
örtük kilitlerden daha: İlk olarak, uygulamanın bir kilit almaya çalışması gerekiyorsa ancak
sonsuza kadar bekleyemez, Lock arabirimi tryLock adında bir yöntem içerir .
bir zaman sınırı parametresi alır. Kilit süre içerisinde alınmaz ise,
yürütme, tryLock çağrısını izleyen ifadede devam eder . İkinci,

Sayfa 634
13.8 C# Konuları 613
açık kilitler, kilit açma çiftlerine sahip olmanın uygun olmadığı durumlarda kullanılır.
blok yapılı. Örtük kilitler her zaman bileşiğin sonunda açılır
kilitli oldukları ifade. Açık kilitler her yerde açılabilir
programın yapısından bağımsız olarak kodda.
Açık kilitler kullanmanın bir tehlikesi (ve örtük
kilitler), kilit açmanın atlanmasıdır. Örtülü kilitler, örtük olarak şurada açılır:
kilitli bloğun sonu. Ancak, açık kilitler, açık bir şekilde belirlenene kadar kilitli kalır.
kilidi açıldı, ki bu potansiyel olarak asla olamaz.
Daha önce belirtildiği gibi, her nesnenin kendine özgü bir koşul kuyruğu vardır.
nesne üzerinde bir koşul bekleyen iş parçacıklarını depolar. Bekleme , bildirmek ve
notifyAll yöntemleri, bir içsel koşul kuyruğu için API'dir. Çünkü
her nesnenin yalnızca bir koşul kuyruğu olabilir, bir kuyruğun içinde iş parçacıkları olabilir
farklı koşullar bekleniyor. Örneğin, arabellek örneğimizin kuyruğu
Kuyruk , iki koşuldan birini bekleyen iş parçacıklarına sahip olabilir ( dolu ==
queSize veya doldurulmuş == 0 ). Tamponun bildirim kullanmasının nedeni budur.
hepsi . ( notify kullanılırsa , yalnızca bir iş parçacığı uyandırılır ve
gerçekte olandan farklı bir durumu bekleyen biri
true.) Bununla birlikte, notifyAll'ın kullanımı pahalıdır, çünkü tüm dizileri uyandırır.
bir nesne üzerinde beklemek ve hangisinin hangisi olduğunu belirlemek için herkesin durumunu kontrol etmesi gerekir.
koşar. Ayrıca, durumlarını kontrol etmek için önce kilidi almaları gerekir.
nesne üzerinde.
İçsel durum kuyruğunu kullanarak bir alternatiftir Durumu
Lock nesnesiyle ilişkili bir koşul kuyruğu kullanan arabirim . Ayrıca
alternatifler beyan bekleyin , haber ve notifyAll adlı bekliyoruz , sin-
nal ve sinyalAll . ile herhangi bir sayıda Koşul nesnesi olabilir.
bir Kilit nesnesi. İle Durum , sinyal yerine signalAll olabilir
kısmen kullanıldığı için hem anlaşılması daha kolay hem de daha verimli olan kullanılır.
daha az bağlam anahtarıyla sonuçlanır.
13.7.8 Değerlendirme
Java'nın eşzamanlılık desteği nispeten basit ama etkilidir. Tüm Java çalıştırma
yöntemler aktör görevleridir ve bunun dışında iletişim için bir mekanizma yoktur.
Ada görevleri arasında olduğu gibi paylaşılan veriler aracılığıyla. Ağır oldukları için
iş parçacıkları, Ada'nın görevleri farklı işlemcilere kolayca dağıtılabilir; özellikle
lar, farklı belleklerde olabilen farklı belleklere sahip farklı işlemciler
farklı yerlerde bilgisayarlar. Bu tür sistemlerle mümkün değildir.
Java'nın konuları.
13.8 C# Konuları
C#'ın threadleri Java'nınkileri temel alıyor olsa da, önemli
farklılıklar. Aşağıda C# iş parçacıklarına kısa bir genel bakış verilmiştir.

Sayfa 635
614
Bölüm 13 Eşzamanlılık
13.8.1 Temel İplik İşlemleri
Java'da olduğu gibi, yalnızca run adlı yöntemler yerine , herhangi bir C# yöntemi kendi içinde çalıştırılabilir.
kendi iş parçacığı. C# iş parçacıkları oluşturulduğunda, bir örnekle ilişkilendirilirler.
önceden tanımlanmış bir temsilcinin ThreadStart . Bir iş parçacığının yürütülmesi başlatıldığında,
temsilcisi, çalıştırması gereken yöntemin adresine sahiptir. Yani, yürütme
iş parçacığının ilişkili temsilcisi aracılığıyla kontrol edilir.
AC# thread, bir Thread nesnesi yaratılarak oluşturulur . Konu inşaatlarda
tor, gönderilmesi gereken ThreadStart örneğinin bir örneğine gönderilmelidir.
iş parçacığında çalıştırılacak yöntemin adı. Örneğin, sahip olabiliriz
public void MyRun1() { . . . }
. . .
Thread myThread = new Thread( new ThreadStart(MyRun1));
Bu örnekte, temsilcisine işaret eden myThread adında bir iş parçacığı oluşturuyoruz .
MyRun1 yöntemi . Böylece, iş parçacığı yürütmeye başladığında yöntemi çağırır.
Adresi temsilcisinde olan. Bu örnekte, myThread temsilcidir ve
MyRun1 yöntemdir.
Java'da olduğu gibi, C#'ta da iki iş parçacığı kategorisi vardır: aktörler ve sunucular.
Aktör konuları özel olarak çağrılmaz; daha doğrusu başlatılır. Ayrıca, met-
yürüttükleri ods parametre almaz veya değer döndürmez. Java'da olduğu gibi,
bir iş parçacığı oluşturmak, eşzamanlı yürütmesini başlatmaz. Oyuncu konuları için,
yürütme, Thread sınıfının bir yöntemi aracılığıyla istenmelidir , bu
olduğu gibi Start adlı vaka
myThread.Start();
Java'da olduğu gibi, bir iş parçacığı başka bir iş parçacığının işini bitirmesini beklemek için yapılabilir.
devam etmeden önce, benzer şekilde adlandırılmış Join yöntemini kullanarak yürütme . İçin
örneğin, A iş parçacığının aşağıdaki çağrıya sahip olduğunu varsayalım :
B.Birleştir();
Konu A parçacığı kadar engellenir B çıkışlarında.
Üyelik yöntem alabilir int bir zaman limiti belirten parametre,
arayanın iş parçacığının bitmesini bekleyeceği milisaniye cinsinden.
Uyku ile belirli bir süre için bir iş parçacığı askıya alınabilir ,
bunlardan bir kamu statik yöntemdir Konu . Uyku parametresi bir
tam sayı milisaniye. Onun Java akrabası aksine, C # 'ın Uyku yok
istisnaları kaldırın, bu nedenle bir try bloğunda çağrılmasına gerek yoktur .
Abort yöntemiyle bir iş parçacığı sonlandırılabilir , ancak
kelimenin tam anlamıyla ipliği öldür. Bunun yerine ThreadAbortException'ı atar .
iplik yakalayabilir. İş parçacığı bu istisnayı yakaladığında, genellikle serbest bırakır
tahsis ettiği herhangi bir kaynak ve sonra biter (kodunun sonuna ulaşarak).
Bir sunucu iş parçacığı, yalnızca temsilcisi aracılığıyla çağrıldığında çalışır. bu konular
istendiğinde bazı hizmetler sağladıkları için sunucular denir. sunucu

Sayfa 636
13.8 C# Konuları 615
diziler aktör dizilerinden daha ilgi çekicidir çünkü genellikle
diğer iş parçacıkları ve genellikle yürütmelerinin diğer iş parçacıklarıyla senkronize olması gerekir.
Bölüm 9'dan herhangi bir C# yönteminin dolaylı olarak çağrılabileceğini hatırlayın.
bir delege. Bu tür çağrılar, temsilci nesneye sanki bir nesneymiş gibi davranılarak yapılabilir.
yöntemin adı. Bu aslında bir çağrıya yapılan çağrının kısaltmasıydı.
Invoke adlı egate yöntemi . Bu nedenle, bir temsilci nesnesinin adı chgfun1 ise ve
başvurduğu yöntem bir int parametresi alır , bu yöntemi çağırabiliriz
aşağıdaki ifadelerden biriyle:
chgfun1(7);
chgfun1.Invoke(7);
Bu çağrılar senkronizedir; yani, yöntem çağrıldığında, arayan
Yöntemin yürütülmesini tamamlayana kadar engellenir. C# ayrıca eşzamansızı da destekler
iş parçacıklarında yürütülen yöntemlere yapılan çağrılar. Bir iş parçacığı eşzamansız olarak çağrıldığında,
Arayan iş parçacığı ve arayan iş parçacığı aynı anda yürütülür, çünkü arayan
çağrılan iş parçacığının yürütülmesi sırasında engellenmez.
Bir iş parçacığı, temsilci örneği yöntemi aracılığıyla eşzamansız olarak çağrılır
Delme yöntemi için parametrelerin gönderildiği BeginInvoke ,
egate, iki ek parametreyle birlikte, biri AsyncCallback türünden ve
nesne türünden diğeri . BeginInvoke uygulayan bir nesne döndürür
ıasyncresult arayüzü. Temsilci sınıfı ayrıca EndIn-
VoKe Çeşidi bir parametre alır Örnek yöntemi, ıasyncresult
ve içinde kapsüllenen yöntem tarafından döndürülen aynı türü döndürür.
temsilci nesnesi. Bir iş parçacığını eşzamansız olarak çağırmak için onu BeginInvoke ile çağırırız .
Şimdilik , son iki parametre için null kullanacağız . Diyelim ki
aşağıdaki yöntem bildirimi ve iş parçacığı tanımı:
genel kayan nokta MyMethod1( int x);
. . .
Thread myThread = new Thread( new ThreadStart(MyMethod1));
Aşağıdaki ifade MyMethod'u eşzamansız olarak çağırır :
IAsyncResult sonuç = myThread.BeginInvoke(10, null ,
boş );
Çağrılan iş parçacığının dönüş değeri EndInvoke yöntemiyle alınır,
tarafından döndürülen nesneyi ( IAsyncResult türünden ) parametresi olarak alır .
Invoke'u başlatın . EndInvoke , çağrılan iş parçacığının dönüş değerini döndürür. İçin
örneğin, MyMethod çağrısının kayan nokta sonucunu almak için ,
aşağıdaki ifade:
float returnValue = EndInvoke(sonuç);
Çağrılan iş parçacığı yürütülürken arayan kişinin biraz çalışmaya devam etmesi gerekiyorsa,
çağrılan iş parçacığının ne zaman biteceğini belirlemenin bir yolu olmalıdır. Bunun için,

Sayfa 637
616
Bölüm 13 Eşzamanlılık
ıasyncresult arayüzü tanımlayan IsCompleted özelliği. Sırasında
çağrılan iş parçacığı yürütülüyorsa, arayan kişi yürütebileceği kodu bir
IsCompleted öğesine bağlı olan while döngüsü . Örneğin, sahip olabiliriz
Takip etmek:
IAsyncResult sonuç = myThread.BeginInvoke(10, null , null );
while (!result.IsCompleted) {
// Biraz hesaplama yap
}
Bu, çağıran iş parçacığında bir şeyi başarmanın etkili bir yoludur.
çağrılan iş parçacığının işini tamamlamasını beklemek. Ancak, eğer miktarı
while döngüsündeki hesaplama nispeten küçüktür, bu verimsiz bir yoldur
bu süreyi kullanın ( IsCompleted testi için gereken süre nedeniyle ). bir alterna-
tive, çağrılan iş parçacığına bir geri arama yönteminin adresiyle bir temsilci vermektir.
ve bittiğinde bu yöntemi çağırmasını sağlayın. Delege olarak gönderilir.
BeginInvoke için ikinci son parametre . Örneğin, aşağıdakileri göz önünde bulundurun
BeginInvoke'a çağrı :
IAsyncResult sonuç = myThread.BeginInvoke(10,
yeni AsyncCallback(MyMethodComplete), null );
Geri arama yöntemi arayanda tanımlanır. Bu tür yöntemler genellikle basitçe
örnek adında bir Boole değişkeni, set isDone için gerçek . nasıl olursa olsun
çağrılan iş parçacığı uzun sürerse, geri arama yöntemi yalnızca bir kez çağrılır.
13.8.2 İş Parçacıklarını Senkronize Etme
C# iş parçacıklarını senkronize etmenin üç farklı yolu vardır:
Kilitli sınıf, System.Threading'den Monitor sınıfı
ad alanı ve kilit ifadesi. Bu mekanizmaların her biri tasarlanmış
belirli bir ihtiyaç için. İçten kilitli sınıf kullanıldığında yalnızca operasyonlar
senkronize edilmesi gereken, bir
tamsayı. Bu işlemler, iki Inter- yöntemi ile atomik olarak yapılır.
olarak bir tamsayıya referans alan kilitli , Artırma ve Azaltma
parametre. Örneğin, ortak bir tamsayıdır adlı artırmak için sayaç olarak
bir iş parçacığı, kullanabiliriz
Interlocked.Increment( ref sayacı);
Kilit deyim dizisindeki kod kritik bir bölümünü işaretlemek için kullanılır.
Bunun sözdizimi aşağıdaki gibidir:
kilit ( belirteç ) {
// kritik bölüm
}

Sayfa 638
13.8 C# Konuları 617
Senkronize edilecek kod özel bir örnek yöntemindeyse, belirteç şudur:
geçerli nesne, bu nedenle bu , kilit için belirteç olarak kullanılır . Eğer kod senkronize edilecekse-
chronized, genel bir örnek yöntemindeyse, yeni bir nesne örneği oluşturulur
(senkronize edilecek kod ile yöntemin sınıfında) ve bir referans
ona kilit için belirteç olarak kullanılır .
Monitör sınıfı beş yöntem tanımlar girin , Bekle , Nabız , PulseAll ,
ve Çıkış , senkronizasyon üzerinde daha fazla kontrol sağlamak için kullanılabilir.
İş Parçacığı. Giriş , parametre olarak bir nesne başvurusu alır yöntem olup,
o nesne üzerinde iş parçacığının senkronizasyonunun başlangıcını işaretler. Bekle
yöntem, iş parçacığının yürütülmesini askıya alır ve Ortak Dil'e talimat verir
Bu iş parçacığının bir sonraki yürütmeye devam etmek istediği .NET'in çalışma zamanı (CLR)
zaman bir fırsat vardır. Nabız da bir nesne alır yöntem olup,
parametresi olarak başvuru, bekleyen bir iş parçacığına artık bir şansı olduğunu bildirir
tekrar koşmak için. PulseAll Java'nın benzer notifyAll . Konular
wait, Wait yöntemi olarak adlandırdıkları sırayla çalıştırılır . Çıkış
yöntem, iş parçacığının kritik bölümünü sonlandırır.
Kilit böylece deyim, bir monitör haline derlenmektedir kilit steno içindir
bir ekran. Ek kontrol (örneğin,
Bekle ve PulseAll ) gereklidir.
.NET 4.0, genel eşzamanlı veri yapılarının bir koleksiyonunu ekledi,
kuyruklar, yığınlar ve çantalar için yapılar dahil. 9 Bu yeni sınıflar
iş parçacığı güvenli, yani çok iş parçacıklı bir programda kullanılabilecekleri anlamına gelir.
programcının rekabet senkronizasyonu hakkında endişelenmesini gerektiriyor.
System.Collections.Concurrent ad, bu sınıfları tanımlar
adları ConcurrentQueue<T> , ConcurrentStack<T> ve
EşzamanlıBag<T> . Böylece üretici-tüketici kuyruk programımız şöyle olabilir:
veri yapısı için bir ConcurrentQueue<T> kullanılarak C# ile yazılmıştır ve orada
bunun için yarışma senkronizasyonunu programlamaya gerek kalmayacaktı. Çünkü
bu eşzamanlı koleksiyonlar .NET'te tanımlanmıştır, ayrıca tüm
diğer .NET dillerinden.
13.8.3 Değerlendirme
C#'ın iş parçacıkları, öncülü Java'nın iş parçacıklarına göre küçük bir gelişmedir. İçin
bir şey, herhangi bir yöntem kendi iş parçacığında çalıştırılabilir. Bunu Java'da hatırlayın, yalnızca
run adlı yöntemler kendi iş parçacıklarında çalışabilir. Java, oyuncu dizilerini destekler
yalnızca, ancak C# hem aktör hem de sunucu dizilerini destekler. İplik sonlandırma da
C# ile temizleyici (bir yöntemi çağırmak ( Abort )
iş parçacığının işaretçisi null ). İş parçacığı yürütme senkronizasyonu daha karmaşıktır.
C# ile işaretlenmiştir, çünkü C# her biri belirli bir işlev için birkaç farklı mekanizmaya sahiptir.
uygulama. Java'nın Lock değişkenleri, C#'ın kilitlerine benzer, bunun dışında
Java'da, bir kilit açma çağrısı ile bir kilidin açık bir şekilde kilidi açılmalıdır . Bu sağlar
hatalı kod oluşturmanın bir yolu daha. Java'nınkiler gibi C# iş parçacıkları hafiftir.
ağırlık, dolayısıyla daha verimli olmalarına rağmen Ada'nınki kadar çok yönlü olamazlar.
9. Çantalar, sıralanmamış nesne koleksiyonlarıdır.

Sayfa 639
618
Bölüm 13 Eşzamanlılık
görevler. Eşzamanlı toplama sınıflarının mevcudiyeti başka bir avantajdır
C#, bu bölümde tartışılan diğer işlevsel olmayan dillerin üzerindedir.
13.9 İşlevsel Dillerde Eşzamanlılık
Bu bölüm, çeşitli uygulamalarda eşzamanlılık desteğine ilişkin kısa bir genel bakış sağlar.
fonksiyonel programlama dilleri.
13.9.1 Çoklu Nokta
Multilisp (Halstead, 1985), programa izin veren bir Scheme uzantısıdır.
eşzamanlı olarak yürütülebilecek program bölümlerini belirtmek için gramer.
Bu eşzamanlılık biçimleri örtüktür; programcı basitçe anlatıyor
derleyici (veya yorumlayıcı) programın çalıştırılabilen bazı bölümleri
aynı anda.
Bir programcının sisteme olası durumlar hakkında bilgi verme yollarından biri.
para birimi pcall yapısıdır. Bir işlev çağrısı bir pcall'a gömülüyse
yapı, işlevin parametreleri eşzamanlı olarak değerlendirilebilir. İçin
örneğin, aşağıdaki pcall yapısını göz önünde bulundurun :
(PCall fabcd)
a , b , c ve d parametreleriyle f işlevidir . Etkisi pcall olduğunu
fonksiyonun parametrelerinin aynı anda değerlendirilebilmesi (herhangi biri veya tümü)
parametrelerin karmaşık ifadeleri olabilir). Ne yazık ki, ya
Bu işlem, ifadenin anlamını etkilemeden güvenle kullanılabilir.
fonksiyon değerlendirmesi, programcının sorumluluğundadır. Bu aslında bir
dil yan etkilere izin vermiyorsa veya programcı
işlevi yan etkileri olmayacak veya en azından sınırlı yan etkileri olacak şekilde tasarladı.
Bununla birlikte, Multilisp bazı yan etkilere izin verir. Eğer fonksiyon yazılmamışsa-
yan etkilerden kaçınmak için on, programcının belirlemesi zor olabilir
ister pcall güvenle kullanılabilir.
Gelecekteki Multilisp yapı potansiyel bir daha ilginç ve bir
daha üretken eşzamanlılık kaynağı. pcall'da olduğu gibi , bir işlev çağrısı
gelecekteki bir yapıya sarılmış . Böyle bir fonksiyon ayrı bir şekilde değerlendirilir.
iş parçacığı, yürütmeye devam eden üst iş parçacığı ile. ana iş parçacığı
fonksiyonun dönüş değerini kullanması gerekene kadar devam eder. eğer fonksiyon
sonucu gerektiğinde yürütmesini tamamlamadı, ana iş parçacığı
devam etmeden önce olana kadar bekler.
Bir fonksiyonun iki veya daha fazla parametresi varsa, bunlar da sarılabilir.
gelecekteki yapılar, bu durumda değerlendirmeleri aynı anda yapılabilir
ayrı iplerde.
Bunlar, Multilisp'teki Scheme'e yapılan tek eklemelerdir.

Sayfa 640
13.9 İşlevsel Dillerde Eşzamanlılık 619
13.9.2 Eşzamanlı Makine Öğrenimi
Eşzamanlı ML (CML), bir dizi iş parçacığı içeren ML'nin bir uzantısıdır
ve eşzamanlılığı desteklemek için geçen bir senkron mesaj biçimi. Lan-
guage tamamen Reppy'de (1999) anlatılmıştır.
CML'de spawn primitifi ile bir iş parçacığı oluşturulur , bu da
parametresi olarak işlev görür. Çoğu durumda, işlev anonim olarak belirtilir.
fare işlevi. İş parçacığı oluşturulur oluşturulmaz, işlev yürütmeye başlar.
yeni iş parçacığında. Fonksiyonun dönüş değeri atılır. bu
fonksiyonun etkileri ya çıktı üretilir ya da iletişim yoluyla
diğer ipliklerle. Ya ana iş parçacığı (yenisini doğuran
iş parçacığı) veya alt iş parçacığı (yeni olan) önce sonlandırılabilir ve
diğerinin yürütülmesini etkiler.
Kanallar, iş parçacıkları arasında iletişim araçları sağlar. bir chan-
nel, kanal yapıcısı ile oluşturulur . Örneğin, aşağıdaki durum-
ment, mychannel adlı rastgele türde bir kanal oluşturur :
val mychannel = kanal() olsun
Kanallardaki iki ana işlem (işlev) göndermek içindir.
( Send ) ve alma ( recv ) iletileri. Mesajın türü belirlenir
gönderme işleminden. Örneğin, aşağıdaki işlev çağrısı,
tamsayı değeri 7 ve bu nedenle kanalın tipinin daha sonra olduğu sonucuna varılır.
tam sayı:
gönder(kanalım, 7)
Recv fonksiyon isimleri, parametre olarak bir kanal. Onun dönüş değeri
aldığı değer.
CML iletişimleri senkronize olduğundan, her ikisi de bir mesaj gönderilir.
ve yalnızca hem gönderici hem de alıcı hazır olduğunda alınır. eğer bir iş parçacığı
bir kanala bir mesaj gönderir ve bu konuda başka hiçbir ileti dizisi almaya hazır değildir
kanal, gönderen engellenir ve başka bir iş parçacığının bir recv yürütmesini bekler
kanalda. Benzer şekilde, bir kanalda bir kanal tarafından bir recv yürütülürse ancak
diğer iş parçacığı o kanala bir mesaj gönderdi, recv'yi çalıştıran iş parçacığı
engellenir ve o kanalda bir mesaj bekler.
Kanallar tür olduğundan, işlevler bunları parametre olarak alabilir.
Ada'nın eşzamanlı mesajının geçişinde olduğu gibi, bir sorun
CML senkron mesaj geçişi, hangi mesajın ne zaman seçileceğine karar vermektir.
birden fazla kanal bir tane aldı. Ve aynı çözüm kullanılır:
korumalı komut do - mesajlar arasında rastgele seçim yapan od yapısı
farklı kanallara.
CML'nin senkronizasyon mekanizması olaydır . Bir açıklama
Bu karmaşık mekanizmanın ayrıntıları bu bölümün kapsamı dışındadır (ve bu
kitap).

Sayfa 641
620
Bölüm 13 Eşzamanlılık
13.9.3 F#
Eşzamanlılık için F# desteğinin bir kısmı aynı .NET sınıflarını temel alır
C# tarafından kullanılan, özellikle System.Threading.Thread . Örneğin,
myConMethod işlevini kendi iş parçacığında çalıştırmak istediğimizi varsayalım . bu
aşağıdaki işlev çağrıldığında iş parçacığını oluşturacak ve yürütmeyi başlatacaktır.
yeni iş parçacığındaki işlevin:
izin =) (CreateThread
let newThread = new Thread(myConMethod)
newThread.Start()
C#'ta önceden tanımlanmış bir temsilcinin örneğini oluşturmanın gerekli olduğunu hatırlayın,
ThreadStart , yapıcısına alt programın adını gönderin ve
Thread yapıcısına parametre olarak yeni temsilci örneği . F#'da, eğer bir
işlev, parametresi, lambda ifadesi veya işlevi olarak bir temsilci bekler
gönderilebilir ve derleyici, temsilciyi göndermişsiniz gibi davranacaktır. Yani, içinde
kodunun üzerinde, işlev myConMethod için parametre olarak gönderilen Konu
yapıcı, ancak gerçekte gönderilen, ThreadStart'ın yeni bir örneğidir (
hangi myConMethod gönderildi ) .
Konu sınıfı tanımlar Uyku gelen iplik koyar yöntemi,
kendisine gönderilen milisaniye sayısı kadar uyumaya çağrılır.
parametre.
Paylaşılan değişmez veriler arasında senkronizasyon gerektirmez
ona erişen iş parçacıkları. Ancak, paylaşılan veriler değiştirilebilir ise, bu olasıdır.
F# ile mümkünse, paylaşılan verilerin bozulmasını önlemek için kilitleme gerekli olacaktır
değiştirmeye çalışan birden fazla iş parçacığı tarafından. Değişken bir değişken kilitlenebilir
nesneye senkronize erişim sağlamak için bir işlev üzerinde çalışırken
ile kilit fonksiyonu. Bu fonksiyon iki parametre alır, bunlardan ilki
değiştirilecek değişkendir. İkinci parametre bir lambda ifadesidir.
bu değişkeni değiştirir.
Değişken bir yığınla ayrılmış değişken ref türündedir . Örneğin, takip-
ing bildirimi , başlangıç ​​değeri 0 olan sum adında böyle bir değişken oluşturur :
izin toplamı = ref 0
Bir ref tipi değişken, aşağıdakileri kullanan bir lambda ifadesinde değiştirilebilir:
ALGOL/Pascal/Ada atama operatörü, := . Ref değişken ön olmalıdır
değerini almak için bir ünlem işareti ( ! ) ile sabitlenir . Aşağıda, muta-
ble değişken toplamı kilitlenirken lambda ifadesi buna x değerini ekler :
kilit(toplam) ( eğlence () -> toplam := !sum + x)
Konular, aynı C# ile olduğu gibi, eşzamansız olarak çağrılabilir.
alt programlar, BeginInvoke ve EndInvoke yanı sıra IAsyncResult
yürütülmesinin tamamlanmasının belirlenmesini kolaylaştırmak için arayüz
zaman uyumsuz olarak adlandırılan iş parçacığı.

Sayfa 642
13.10 İfade Düzeyinde Eşzamanlılık 621
Daha önce belirtildiği gibi, F#, .NET'in eşzamanlı genel koleksiyonlarına sahiptir.
programlarında kullanılabilir. Bu, çok fazla programlama çabasından tasarruf sağlayabilir
içinde paylaşılan bir veri yapısına ihtiyaç duyan çok iş parçacıklı programlar oluştururken
sıra, yığın veya çanta şeklindedir.
13.10 İfade Düzeyinde Eşzamanlılık
Bu bölümde, ifade düzeyinde bağlam için dil tasarımına kısa bir göz atacağız.
para birimi. Dil tasarımı açısından, bu tür tasarımların amacı
programcının derleyiciyi bilgilendirmek için kullanabileceği bir mekanizma sağlamaktır.
programı çok işlemcili bir mimariye eşlemenin yolları. 10
Bu bölümde, bir dilden yalnızca bir dilbilimsel yapı koleksiyonu,
ifade düzeyinde eşzamanlılık için ölçü tartışıldı: Yüksek Performanslı Fortran.
13.10.1 Yüksek Performanslı Fortran
Yüksek Performanslı Fortran (HPF; ACM, 1993b) bir uzantılar koleksiyonudur.
programcıların bilgi belirtmesine izin vermek için tasarlanmış Fortran 90'a
derleyici, programların çoklu işlemlerde yürütülmesini optimize etmesine yardımcı olur.
sor bilgisayarlar. HPF, hem yeni spesifikasyon bildirimlerini hem de dahili
sic veya yerleşik alt programlar. Bu bölümde HPF'nin yalnızca bir kısmı ele alınmaktadır.
ifadeler.
HPF'nin birincil belirtim ifadeleri, sayıyı belirtmek içindir.
işlemcilerin sayısı, verilerin bu işlemlerin bellekleri üzerinde dağıtılması
sors ve verilerin diğer verilerle bellek yerleşimi açısından hizalanması.
HPF belirtim ifadeleri, bir Fortran'da özel yorumlar olarak görünür.
programı. Her biri !HPF$ öneki ile tanıtılır , burada ! karakter mi-
acter Fortran 90'da yorum satırlarına başlamak için kullanılırdı. Bu önek onları
Fortran 90 derleyicileri için görünmez, ancak HPF derleyicilerinin tanıması kolaydır.
İŞLEMCİ özellikleri aşağıdaki biçime sahiptir:
!HPF$ İŞLEMCİ işlemleri (n)
Bu ifade, derleyiciye hangi işlemcilerin kullanılacağını belirtmek için kullanılır.
bu program için oluşturulan kod tarafından kullanılabilir. Bu bilgi kullanılır
derleyiciye verilerin nasıl olması gerektiğini söylemek için diğer özelliklerle birlikte
işlemcilerle ilişkili belleklere dağıtılır.
DISTRIBUTE ve ALIGN özellikleri informa- sağlamak için kullanılan
Belleği paylaşmayan makinelerde, yani her biri
İşlemcinin kendi belleği vardır. Varsayım, bir işlemci tarafından erişimin
kendi belleğine erişim, başka bir işlemcinin belleğine erişimden daha hızlıdır.
10. Her ne kadar ALGOL 68, ifadelerle ilgilenmesi amaçlanan bir semafor türü içerse de-
düzeyde eşzamanlılık, burada semaforların bu uygulamasını tartışmıyoruz.

Sayfa 643
622
Bölüm 13 Eşzamanlılık
DISTRIBUTE veriler dağıtılmak üzere ne deyim belirliyorsa ve
kullanılacak dağıtım türü. Şekli aşağıdaki gibidir:
!HPF$ DISTRIBUTE ( tür ) ONTO procs :: identifier_list
Bu açıklamada tür BLOCK veya CYCLIC olabilir . Tanımlayıcı listesi,
dağıtılacak dizi değişkenlerinin adları. Belirli bir değişken
olduğu fied BLOCK dağıtılmış ayrılmıştır n eşit gruba, her bir grubun
üzerine eşit olarak dağıtılmış dizi öğelerinin bitişik koleksiyonlarından oluşur.
tüm işlemcilerin bellekleri. Örneğin, 500 elemanlı bir dizi
adlı LIST , beş işlemciye dağıtılan BLOK'tur , ilk 100 öğesi
LIST ilk işlemcinin belleğinde, ikinci 100 işlemcinin belleğinde saklanacaktır.
ikinci işlemcinin belleği vb. Bir CYCLIC dağıtım belirtir
dizinin bireysel öğelerinin, dizinin belleklerinde döngüsel olarak depolandığını
işlemciler Örneğin, eğer LİSTESİ edilir CYCLIC dağıtılan tekrar tekrar beş prosesini görünür
sıcaklık hissedicisi, ilk elemanı LİSTESİ birinci prosesini görünür belleğinde saklanır
sor, ikinci işlemcinin belleğindeki ikinci öğe vb.
ALIGN ifadesinin formu şu şekildedir:
ALIGN array1_element İLE array2_element
ALIGN , bir dizinin dağılımını diğerininkiyle ilişkilendirmek için kullanılır. İçin
örnek,
list1(index) İLE list2(index+1) ALIGN
belirtir endeksi unsuru Liste1 olduğu anısına saklanmasına
aynı işlemci endeksi + 1 elemanın list2 tüm değerleri için, dizin .
Bir ALIGN içindeki iki dizi referansı , bazı ifadelerde birlikte görünür.
programı. Bunları aynı belleğe yerleştirme (bu, aynı işlemci anlamına gelir)
referansların mümkün olduğunca yakın olmasını sağlar.
Aşağıdaki örnek kod segmentini göz önünde bulundurun:
GERÇEK liste_1 (1000), liste_2 (1000)
INTEGER list_3 (500), list_4 (501)
!HPF$ İŞLEMCİLERİ proc (10)
!HPF$ İŞLEMLERİNE DAĞIT (BLOK) :: list_1, list_2
!HPF$ list_3 (indeks) İLE list_4 (indeks+1) ALIGN
. . .
list_1 (indeks) = list_2 (indeks)
list_3 (indeks) = list_4 (indeks+1)
Bu atama ifadelerinin her yürütülmesinde, başvurulan iki dizi
elemanlar aynı işlemcinin belleğinde saklanacaktır.
HPF belirtim ifadeleri, derleyici için bilgi sağlar
ürettiği kodu optimize etmek için kullanabileceği veya kullanmayabileceği. ne derleyici
aslında, gelişmişlik düzeyine ve belirli mimarisine bağlıdır.
hedef makinenin ture.

Sayfa 644
Özet 623
Forall'dır deyimi atama ifadeleri o dizisini belirtir
eşzamanlı olarak yürütülebilir. Örneğin,
FORALL (indeks = 1:1000)
list_1(indeks) = list_2(indeks)
SON DERECE
list_2 öğelerinin ilgili ele-
ait ments list_1 . Ancak, atamalar aşağıdakilerle sınırlıdır:
sıra: önce tüm 1.000 atamanın sağ tarafı değerlendirilmelidir.
herhangi bir atama gerçekleşir. Bu, tüm işlemlerin aynı anda yürütülmesine izin verir.
atama ifadeleri. Atama açıklamalara ek olarak, forall'dır devlet
mentler bir FORALL yapısının gövdesinde görünebilir . Forall'dır ifadesi
aynı talimatın uygulandığı vektör makineleriyle iyi bir eşleşme
genellikle bir veya daha fazla dizide birçok veri değeri. HPF FORALL açıklaması
Fortran 95 ve sonraki Fortran sürümlerinde bulunur.
HPF'nin yeteneklerinin sadece küçük bir kısmını kısaca tartıştık.
Bununla birlikte, okuyucuya türler hakkında bir fikir vermek yeterli olmalıdır.
muhtemelen bilgisayarları programlamak için yararlı olan dil uzantıları
çok sayıda işlemci.
C# 4.0 (ve diğer .NET dilleri), aşağıdaki iki yöntemi içerir:
biraz FORALL gibi davranın . Bunlar, içinde bulunduğu döngü kontrol ifadeleridir.
yinelemeler açılabilir ve gövdeler aynı anda yürütülebilir. Bunlar
Hangi Parallel.For ve Parallel.ForEach .
ÖZET
Eşzamanlı yürütme talimat, deyim veya alt program düzeyinde olabilir.
Birden çok işlemci gerçekte olduğunda fiziksel eşzamanlılık ifadesini kullanırız.
eşzamanlı birimleri yürütmek için kullanılır. Eşzamanlı birimler tek bir üzerinde yürütülürse
işlemci, mantıksal eşzamanlılık terimini kullanıyoruz . Temel kavramsal model
tüm eşzamanlılık mantıksal eşzamanlılık olarak adlandırılabilir .
Çoğu çok işlemcili bilgisayar iki geniş kategoriden birine girer:
SIMD veya MIMD. MIMD bilgisayarlar dağıtılabilir.
Alt program düzeyini destekleyen dillerin başlıca iki özelliği
eşzamanlılık, paylaşılan veri yapılarına karşılıklı olarak özel erişim sağlamalıdır.
(rekabet senkronizasyonu) ve görevler arasında işbirliği (işbirliği
senkronizasyon).
Görevler beş farklı durumdan herhangi birinde olabilir: yeni, hazır, çalışıyor,
engellendi veya öldü.
Eşzamanlılığı desteklemek için dil yapıları tasarlamak yerine,
bazen OpenMP gibi kitaplıklar kullanılır.
Eşzamanlılık için dil desteğine yönelik tasarım sorunları,
tion ve işbirliği senkronizasyonu sağlanır, bir uygulama nasıl

Sayfa 645
624
Bölüm 13 Eşzamanlılık
Görev zamanlamasını, görevlerin nasıl ve ne zaman yürütülmeye başladığını ve bittiğini etkilemek,
ve nasıl ve ne zaman oluşturuldukları.
Semafor, bir tamsayı ve bir görev tanımından oluşan bir veri yapısıdır.
sıra. Semaforlar hem rekabeti hem de işbirliğini sağlamak için kullanılabilir.
eşzamanlı görevler arasında erasyon senkronizasyonu. Semaforları kullanmak kolaydır
yanlış bir şekilde, derleyici, bağlayıcı,
veya çalışma zamanı sistemi.
Monitörler, sağlamanın doğal bir yolunu sağlayan veri soyutlamalarıdır.
görevler arasında paylaşılan verilere karşılıklı olarak özel erişim. tarafından destekleniyorlar
Ada, Java ve C# gibi çeşitli programlama dilleri. İşbirliği
monitörlerle dillerde senkronizasyon bir şekilde sağlanmalıdır
semaforlar.
İleti ileten eşzamanlılık modelinin altında yatan kavram,
görevlerin, yürütmelerini senkronize etmek için birbirlerine mesajlar göndermesini sağlar.
Ada, mesaj geçişine dayalı karmaşık ama etkili yapılar sağlar.
model, eşzamanlılık için. Ada'nın görevleri ağır işlerdir. Görevler iletişim kurar
senkron iletişim olan randevu mekanizması aracılığıyla birbirleriyle
adaçayı geçiyor. Randevu, tarafından gönderilen bir mesajı kabul eden bir görev eylemidir.
başka bir görev. Ada, hem basit hem de karmaşık kontrol yöntemlerini içerir
görevler arasında buluşma olayları.
Ada 95+, eşzamanlılık desteği için ek yetenekler içerir,
öncelikle korunan nesneler. Ada 95+, monitörleri görevlerle iki şekilde destekler
ve korunan nesnelerle.
Java, nispeten basit ama etkili bir şekilde hafif eşzamanlı birimleri destekler.
yol. Dan herhangi bir sınıf bu da devralır Konu veya aletlerin Runnable
run adlı bir yöntemi geçersiz kılabilir ve bu yöntemin kodunun çalıştırılmasını sağlayabilir.
şu anda bu tür diğer yöntemlerle ve ana programla. Yarışma
senkronizasyon, paylaşılacak verilere erişen yöntemler tanımlanarak belirtilir.
dolaylı olarak senkronize edilmiştir. Küçük kod bölümleri de dolaylı olarak senkronize olabilir.
nizlenmiş. Metodlarının tümü senkronize olan bir sınıf bir monitördür. İşbirliği
senkronizasyon, wait , notify ve notify yöntemleriyle gerçekleştirilir.
hepsi . Konu sınıfı da sağlar uyku , verim , katılmak ve kesme
yöntemler.
Java onun aracılığıyla semaforları sayılması için doğrudan desteği vardır Semaphore
sınıf ve onun edinme ve bırakma yöntemleri. Ayrıca bazı sınıfları vardı
toplama, artırma ve
tamsayılar için eksiltme işlemleri. Java ayrıca açık kilitler sağlar.
Kilit arayüzü ve ReentrantLock sınıfı ve kilitleme ve kilit açma yöntemleri.
Örtülü senkronizasyon için ilave kullanarak olarak senkronize Java sağlar
int , long ve boole tipi değişkenlerin örtük engellemesiz senkronizasyonu
yetenekler, ayrıca referanslar ve diziler. Bu durumlarda, atomik alıcılar, ayarlayıcılar,
toplama, artırma ve eksiltme işlemleri sağlanır.
C#'ın eşzamanlılık desteği Java'ya dayanır, ancak biraz daha fazladır.
komplike. Bir iş parçacığında herhangi bir yöntem çalıştırılabilir. Hem aktör hem de sunucu konuları
Desteklenmektedir. Tüm iş parçacıkları, ilişkili delegeler aracılığıyla kontrol edilir. sunucu
diziler Invoke ile eşzamanlı olarak çağrılabilir veya eşzamansız olarak çağrılabilir

Sayfa 646
Soruları gözden geçir 625
ile BeginInvoke . Çağrılan iş parçacığına bir geri arama yöntemi adresi gönderilebilir.
Interlocked ile üç çeşit iş parçacığı senkronizasyonu desteklenir
Atomik artırma ve eksiltme işlemlerini sağlayan sınıf, Monitor
sınıf ve kilit ifadesi.
Tüm .NET dilleri, genel eşzamanlı veri yapılarını kullanır
rekabet senkronizasyonunun örtük olduğu yığınlar, kuyruklar ve çantalar için.
Multilisp, programcının durumu bilgilendirmesine izin vermek için Şemayı biraz genişletir.
eşzamanlı olarak yürütülebilen program bölümleri hakkında uygulama. bağla-
mevcut ML, bir iş parçacığı biçimini ve bir eşzamanlama biçimini desteklemek için ML'yi genişletir.
bu iş parçacıkları arasında geçen nous mesajı. Bu mesaj geçişi tasarlanmıştır
kanallar ile. F# programlarının tüm .NET destek sınıflarına erişimi vardır
eşzamanlılık için. Değişken olan iş parçacıkları arasında paylaşılan veriler erişime sahip olabilir
senkronize.
High-Performance Fortran, verilerin nasıl kullanılacağını belirten ifadeler içerir.
birden çok işlemciye bağlı bellek birimleri üzerinden dağıtılacaktır.
Ayrıca, aşağıdakileri içeren ifade koleksiyonlarını belirtmek için ifadeler de dahildir:
eşzamanlı olarak yürütülür.
KAYNAKÇA NOTLAR
Genel eşzamanlılık konusu uzun uzadıya Andrews ve
Schneider (1983), Holt ve ark. (1978) ve Ben-Ari (1982).
Monitör konsepti geliştirildi ve Concurrent'da uygulanması
Pascal, Brinch Hansen (1977) tarafından tanımlanmıştır.
Eşzamanlı birimin mesaj ileten modelinin erken gelişimi
kontrol Hoare (1978) ve Brinch Hansen (1978) tarafından tartışılmaktadır. derinlemesine bir
Ada görevlendirme modelinin geliştirilmesine ilişkin tartışma Ichbiah'ta bulunabilir
ve diğerleri (1979). Ada 95, ARM'de (1995) ayrıntılı olarak anlatılmıştır. Yüksek performans
Fortran, ACM'de (1993b) anlatılmıştır.
İNCELEME SORULARI
1. Programlardaki olası üç eşzamanlılık düzeyi nedir?
2. Bir SIMD bilgisayarın mantıksal mimarisini tanımlayın.
3. Bir MIMD bilgisayarının mantıksal mimarisini tanımlayın.
4. SIMD tarafından en iyi desteklenen program eşzamanlılığı düzeyi
bilgisayarlar?
5. MIMD tarafından en iyi desteklenen program eşzamanlılığı düzeyi
bilgisayarlar?
6. Bir vektör işlemcisinin mantıksal mimarisini tanımlayın.
7. Fiziksel ve mantıksal eşzamanlılık arasındaki fark nedir?

Sayfa 647
626
Bölüm 13 Eşzamanlılık
8. Bir programdaki kontrol dizisi nedir?
9. Neden eşyordamlar yarı-eşzamanlı olarak adlandırılıyor?
10. Çok iş parçacıklı program nedir?
11. Eşzamanlılık için dil desteğini incelemek için dört neden nedir?
12. Ağır bir görev nedir? Hafif görev nedir?
13. Görev , senkronizasyon , rekabet ve işbirliği senkronizasyonunu tanımlayın ,
canlılık , yarış durumu ve kilitlenme .
14. Ne tür görevler herhangi bir senkronizasyon gerektirmez?
15. Bir görevin içinde olabileceği beş farklı durumu tanımlayın.
16. Görev tanımlayıcı nedir?
17. Eşzamanlılık için dil desteği bağlamında, koruma nedir?
18. Göreve hazır kuyruğun amacı nedir?
19. Aşağıdakiler için dil desteği için iki temel tasarım sorunu nelerdir?
eşzamanlılık?
20. Semaforlar için bekle ve bırak işlemlerinin eylemlerini tanımlayın.
21. İkili semafor nedir? Sayma semaforu nedir?
22. Sağlamak için semafor kullanmanın temel sorunları nelerdir?
senkronizasyon?
23. Monitörlerin semaforlara göre avantajları nelerdir?
24. Monitörler hangi üç ortak dilde uygulanabilir?
25. Randevu , kabul etme maddesi , giriş maddesi , aktör görevi , sunucu görevi tanımlayın ,
genişletilmiş kabul maddesi , açık kabul maddesi , kapalı kabul maddesi ve com-
dolu görev .
26. Daha genel olan, monitörler aracılığıyla eşzamanlılık veya eşzamanlılık
mesaj yoluyla mı?
27. Ada görevleri statik mi yoksa dinamik olarak mı yaratılıyor?
28. Uzatılmış bir kabul maddesi hangi amaca hizmet eder?
29. Ada görevleri için işbirliği senkronizasyonu nasıl sağlanır?
30. Ada sonlandırmanın amacı nedir ?
31. Ada 95'teki korunan nesnelerin aşağıdakiler için görevlere göre avantajı nedir?
paylaşılan veri nesnelerine erişim sağlamak?
32. Spesifik olarak, hangi Java program birimi ana programla aynı anda çalışabilir?
bir uygulama programında yöntem?
33. Java iş parçacıkları hafif mi yoksa ağır görevler mi?
34. Java uyku yöntemi ne işe yarar?
35. Java getiri yöntemi ne işe yarar?
36. Java birleştirme yöntemi ne işe yarar?
37. Java kesme yöntemi ne işe yarar ?
38. Olduğu bildirilebilecek iki Java yapısı nelerdir?
senkronize mi?

Sayfa 648
Problem Seti 627
39. Java'da bir iş parçacığının önceliği nasıl ayarlanabilir?
40. Java dizileri, aktör dizileri, sunucu dizileri veya herhangi biri olabilir mi?
41. Desteklemek için kullanılan üç Java yönteminin eylemlerini tanımlayın.
işbirliği senkronizasyonu.
42. Bir monitör ne tür bir Java nesnesidir?
43. Java'nın neden Runnable arabirimini içerdiğini açıklayın .
44. Java Semaphore nesneleri ile kullanılan iki yöntem nelerdir ?
45. Java'da bloksuz senkronizasyonun avantajı nedir?
46. ​​Java AtomicInteger sınıfının yöntemleri nelerdir ve
bu sınıfın amacı?
47. Java'da açık kilitler nasıl desteklenir?
48. Bir C# iş parçacığında ne tür yöntemler çalıştırılabilir?
49. C# dizileri aktör dizileri, sunucu dizileri veya herhangi biri olabilir mi?
50. Bir C# iş parçacığının eşzamanlı olarak çağrılabilmesinin iki yolu nelerdir?
51. Bir C# iş parçacığı nasıl eşzamansız olarak çağrılabilir?
52. Eşzamansız olarak adlandırılan bir iş parçacığından döndürülen değer nasıldır?
C# ile alındı ​​mı?
53. Java'nın uykusuna göre C#'ın Sleep yönteminin farkı nedir ?
54. C#'ın Abort yöntemi tam olarak ne yapar ?
55. C#'ın Interlocked sınıfının amacı nedir ?
56. C# kilit deyimi ne işe yarar?
57. Multilisp hangi dili temel alır?
58. Multilisp'in pcall yapısının anlamı nedir ?
59. CML'de bir iş parçacığı nasıl oluşturulur?
60. F# yığınla ayrılmış değiştirilebilir değişkenin türü nedir?
61. Neden F# değişmez değişkenleri bir çoklu ortamda senkronize erişim gerektirmez?
tithreaded program?
62. Yüksek-'in spesifikasyon ifadelerinin amacı nedir?
Performans Fortran?
63. FORALL Yüksek Performans beyanının amacı nedir?
Fortran ve Fortran?
PROBLEM SETİ
1. Rekabet senkronizasyonunun neden bir sorun olmadığını açık bir şekilde açıklayın
eşyordamları destekleyen ancak desteklemeyen bir programlama ortamında
eşzamanlılık
2. Kilitlenme algılandığında bir sistemin yapabileceği en iyi eylem nedir?

Sayfa 649
628
Bölüm 13 Eşzamanlılık
3. Meşgul bekleme, bir görevin belirli bir olay için uygun şekilde beklediği bir yöntemdir.
sürekli olarak o olayın meydana gelip gelmediğini kontrol etmek. asıl sorun nedir
bu yaklaşımla?
4. Bölüm 13.3'ün üretici-tüketici örneğinde,
tüketici sürecinde yayının (erişimin) yanlış değiştirilmesi
ile bekleme (erişim) . Yürütmede bu hatanın sonucu ne olur?
sistemin konusu?
5. Bir bilgisayar için montaj dili programlama üzerine bir kitaptan
Intel Pentium işlemci kullanır, hangi talimatların pro-
semaforların yapımını desteklemek için videolu.
6. A ve B adlı iki görevin Buf_Size paylaşılan değişkenini kullanması gerektiğini varsayalım .
Görev A , Buf_Size öğesine 2 ekler ve B görevi ondan 1 çıkarır. varsayalım ki
bu tür aritmetik işlemler, üç aşamalı getirme işlemiyle yapılır.
mevcut değer, aritmetiği gerçekleştirme ve yeni değeri koyma
geri. Rekabet senkronizasyonunun yokluğunda, hangi diziler
olaylar mümkündür ve bu işlemlerden hangi değerler elde edilir? Farz etmek
Buf_Size'ın başlangıç ​​değeri 6'dır.
7. Java rekabet senkronizasyon mekanizmasını bununla karşılaştırın
Ada'nın.
8. Java işbirliği senkronizasyon mekanizmasını aşağıdakilerle karşılaştırın.
Ada.
9. Bir izleme prosedürü, sistemde başka bir prosedürü çağırırsa ne olur?
aynı monitör?
10. Sema kullanarak işbirliği senkronizasyonunun göreceli güvenliğini açıklayın.
phores ve görevlerde Ada'nın ne zaman yan tümcelerini kullanma .
PROGRAMLAMAALIŞTIRMALAR
1. Genel semaforları uygulamak için bir Ada görevi yazın.
2. Aşağıdaki gibi paylaşılan bir arabelleği yönetmek için bir Ada görevi yazın.
örneğin, ancak Programlama Alıştırması 1'deki semafor görevini kullanın.
3. Ada'daki semaforları tanımlayın ve bunları her iki işbirliğini sağlamak için kullanın
ve paylaşılan arabellek örneğinde rekabet senkronizasyonu.
4. Java kullanarak Programlama Alıştırma 3'ü yazın.
5. Bölümün paylaşılan arabellek örneğini C# ile yazın.
6. Okur-yazar sorunu şu şekilde ifade edilebilir: Paylaşılan bir bellek
konum, herhangi bir sayıda görev tarafından aynı anda okunabilir, ancak
görev, paylaşılan hafıza konumuna yazmalı, özel
erişim. Okuyucu-yazıcı problemi için bir Java programı yazınız.
7. Ada'yı kullanarak Programlama Alıştırma 6'yı yazın.
8. Programlama Alıştırma 6'yı C# kullanarak yazın.

Sayfa 650
629
14.1 Özel Durum Yönetimine Giriş
14.2 Ada'da İstisna İşleme
14.3 C++'da İstisna İşleme
14.4 Java'da İstisna İşleme
14.5 Olay Yönetimine Giriş
14.6 Java ile Olay İşleme
14.7 C#'da Olay İşleme
14
İstisna işleme
ve Olay İşleme

Sayfa 651
630
Bölüm 14 İstisna İşleme ve Olay İşleme
Bu bölümde, ilgili iki bölüm için programlama dili desteği tartışılmaktadır.
birçok çağdaş program: istisna işleme ve olay işleme. Her ikisi de
önceden belirlenemeyen zamanlarda istisnalar ve olaylar meydana gelebilir,
ve her ikisi de en iyi şekilde özel dil yapıları ve süreçleriyle ele alınır. Bazı
bu yapılar ve süreçler - örneğin, yayılma - istisna için benzerdir
işleme ve olay işleme.
İlk olarak, aşağıdakiler de dahil olmak üzere istisna işlemenin temel kavramlarını tanımlıyoruz:
donanım ve yazılım tarafından algılanabilen istisnalar, istisna işleyicileri ve yükseltme
istisnalar. Ardından, istisna işleme için tasarım konuları tanıtılır ve
istisnaların istisna işleyicilere bağlanması da dahil olmak üzere tartışıldı, devam,
varsayılan işleyiciler ve özel durum devre dışı bırakma. Bu bölümün ardından bir açıklama gelir
ve üç programlama alanının istisna işleme olanaklarının bir değerlendirmesi
ölçüler: Ada, C++ ve Java.
Bu bölümün son kısmı olay işleme hakkındadır. Biz ilk olarak bir
olay işlemenin temel kavramlarına giriş. Bunu tartışmalar takip eder
Java ve C#'ın olay işleme yaklaşımları.
14.1 Özel Durum Yönetimine Giriş
Çoğu bilgisayar donanım sistemi, belirli çalışma zamanlarını algılama yeteneğine sahiptir.
kayan nokta taşması gibi hata koşulları. Erken programlama lan-
göstergeler, kullanıcı programı olacak şekilde tasarlanmış ve uygulanmıştır.
bu tür hataları ne tespit edebilir ne de çözmeye çalışabilir. Bu dillerde,
böyle bir hatanın meydana gelmesi, programın sonlandırılmasına neden olur
ve kontrolün işletim sistemine aktarılması. Tipik işletim
bir çalışma zamanı hatasına sistem tepkisi, bir tanılama mesajı görüntülemektir;
anlamlı ve bu nedenle yararlı veya son derece şifreli olabilir. gösterdikten sonra
mesajı, program sonlandırılır.
Ancak, girdi ve çıktı işlemleri söz konusu olduğunda durum biraz-
ne farklı. Örneğin, bir Fortran Read ifadesi girdiyi engelleyebilir.
her ikisi de girdi tarafından algılanan hatalar ve dosya sonu koşulları
cihaz donanımı. Her iki durumda da Read deyimi aşağıdakilerin etiketini belirtebilir:
kullanıcı programında durumla ilgilenen bazı ifadeler. durumda
dosyanın sonunda, koşulun her zaman bir hata olarak değerlendirilmediği açıktır.
Çoğu durumda, bir tür işlemenin olduğuna dair bir sinyalden başka bir şey değildir.
tamamlandı ve başka bir tür başlamalıdır. bariz farka rağmen
dosya sonu ile başarısız bir giriş gibi her zaman hata olan olaylar arasında
işlem, Fortran her iki durumu da aynı mekanizma ile ele alır. Düşünmek
aşağıdaki Fortran Read ifadesi:
Okuma(Birim=5, Fmt=1000, Err=100, Bitiş=999) Ağırlık
Hata hükmü belirtir o kontrol tablosuna transfer edilecek
okuma işleminde bir hata oluşursa 100 olarak etiketlenir . Bitiş hükmü spesifikasyonlara
kontrolün okunması durumunda 999 etiketli ifadeye aktarılması gereken dosyalar

Sayfa 652
14.1 Özel Durum Yönetimine Giriş 631
işlem dosyanın sonuyla karşılaşır. Bu nedenle, Fortran için basit dallar kullanır
hem girdi hataları hem de dosya sonu.
Donanım tarafından algılanamayan ciddi bir hata kategorisi var
ancak derleyici tarafından oluşturulan kod tarafından tespit edilebilir. Örneğin, dizi
alt simge aralık hataları neredeyse donanım, tespit asla 1 ama neden
program yürütülürken genellikle daha sonra fark edilmeyen ciddi hatalar.
Alt simge aralığı hatalarının tespiti bazen dil tarafından gereklidir
tasarım. Örneğin, Java derleyicileri genellikle doğrulamayı kontrol etmek için kod üretir.
her alt simge ifadesinin doğruluğu (bunlar,
bir alt simge ifadesinin sahip olamayacağı derleme zamanında belirlenebilir
aralık dışı bir değer, örneğin, alt simge bir değişmez ise). C'de, alt simge
aralıklar kontrol edilmiyor çünkü bu tür bir kontrolün maliyeti (ve hala öyle) değil
bu tür hataları tespit etmenin yararına olduğuna inanılıyor. Bazı derleyicilerde
bazı diller için alt simge aralığı denetimi seçilebilir (açık değilse
varsayılan olarak) veya kapalı (varsayılan olarak açıksa) programda veya
derleyiciyi çalıştıran komut.
Çoğu çağdaş dilin tasarımcıları mekanizmaları dahil etmişlerdir.
programların belirli çalışma zamanı hatalarına standart bir şekilde tepki vermesini sağlayan
diğer program tarafından algılanan olağandışı olaylar. Programlar ayrıca sertifika verildiğinde de bildirilebilir.
tain olayları donanım veya sistem yazılımı tarafından algılanır, böylece onlar da tepki verebilir.
bu olaylara. Bu mekanizmalara topluca istisna işleme adı verilir.
Belki de bazı dillerin istisna içermemesinin en makul nedeni,
işlem işleme, dile kattığı karmaşıklıktır.
14.1.1 Temel Kavramlar
Hem disk okuma hataları gibi donanım tarafından algılanan hataları hem de
dosya sonu gibi olağandışı durumlar (donanım tarafından da algılanır),
istisna olmak. İstisna kavramını daha da genişletiyoruz.
yazılım tarafından algılanabilen hatalar veya olağandışı koşullar (bir yazılım tarafından
yorumlayıcı veya kullanıcı kodunun kendisi). Buna göre, istisnayı şu şekilde tanımlarız:
donanım veya donanım tarafından algılanabilen, hatalı veya değil, olağandışı herhangi bir olay
yazılımdır ve özel işlem gerektirebilir.
Bir istisna tespit edildiğinde gerekli olabilecek özel işleme
istisna işleme denir . Bu işlem, bir kod birimi veya bölüm tarafından yapılır.
özel durum işleyicisi denir . İlişkili olduğunda bir istisna ortaya çıkar
olay meydana gelir. Bazı C tabanlı dillerde istisnaların atıldığı söyleniyor ,
yükseltmekten ziyade . 2 Farklı istisna türleri farklı istisna gerektirir
işleyiciler. Dosya sonunun tespiti neredeyse her zaman belirli bir program gerektirir
eylem. Ancak, açıkça, bu eylem bir dizi indeksi için de uygun olmaz.
aralık hatası istisnası. Bazı durumlarda, tek eylem, bir
hata mesajı ve programın düzenli bir şekilde sonlandırılması.
1970'lerde 1. Bazı bilgisayarlar vardı ki donanım alt simge aralık hataları algılar.
2. C++, istisna işlemeyi içeren ilk C tabanlı dildi. kelime atmak oldu
standart C kitaplığı yükseltme adlı bir işlev içerdiğinden, yükseltme yerine kullanılır .

Sayfa 653
632
Bölüm 14 İstisna İşleme ve Olay İşleme
Bazı durumlarda, donanım tarafından algılanabilen bazı donanımların göz ardı edilmesi istenebilir.
istisnalar - örneğin, sıfıra bölme - bir süre için. Bu eylem olurdu
istisna devre dışı bırakılarak yapılır. Devre dışı bırakılmış bir istisna yeniden etkinleştirilebilir
daha sonra.
Bir ülkede ayrı veya özel istisna işleme tesislerinin olmaması,
guage, kullanıcı tanımlı, yazılım tarafından algılanan istisnaların ele alınmasını engellemez.
tion. Bir program birimi içinde algılanan böyle bir istisna, genellikle
birimin arayanı veya çağıran. Olası bir tasarım, yardımcı bir parametre göndermektir,
durum değişkeni olarak kullanılır. Durum değişkenine bir değer atanır.
çağrılan alt programın doğruluğuna ve/veya normalliğine göre
hesaplama. Aranan birimden döndükten hemen sonra, arayan kişi test eder.
durum değişkeni. Değer, bir istisna oluştuğunu gösteriyorsa,
Çağıran ünitede bulunabilen işleyici yürürlüğe konulabilir. Birçok C
standart kitaplık işlevleri bu yaklaşımın bir türevini kullanır: Dönüş değerleri
hata göstergeleri olarak kullanılır.
Diğer bir olasılık, alt programa bir etiket parametresi geçirmektir. Nın-nin
Elbette, bu yaklaşım yalnızca etiketlerin kullanılmasına izin veren dillerde mümkündür.
parametreler olarak. Bir etiketin iletilmesi, aranan birimin farklı bir
bir istisna oluşmuşsa arayanın üzerine gelin. İlk alternatifte olduğu gibi,
işleyici genellikle arayan birimin kodunun bir bölümüdür. Bu yaygın bir kullanımdır
Fortran'da etiket parametreleri.
Üçüncü bir olasılık, işleyicinin ayrı bir alt program olarak tanımlanmasıdır.
adı, aranan birime parametre olarak iletilir. Bu durumda, işleyici
alt program arayan tarafından sağlanır, ancak aranan birim,
bir istisna ortaya çıkar. Bu yaklaşımla ilgili bir sorun, birinin gerekli olmasıdır.
bir işleyici alt programı göndermek için her yapılan çağrı her gerçekleştirdiğini altprogramın
işleyici alt programı, gerekli olsun veya olmasın bir parametre olarak. Üstelik,
birkaç farklı istisna türüyle başa çıkmak için, birkaç farklı işleyici
dişlerin geçirilmesi gerekir, bu da kodu karmaşıklaştırır.
Bir istisnanın tespit edildiği birimde ele alınması isteniyorsa,
işleyici o birime bir kod parçası olarak dahil edilir.
İstisna işlemenin yerleşik olarak bulunmasının bazı kesin avantajları vardır.
dil. İlk olarak, istisna işleme olmadan, hatayı tespit etmek için gereken kod
koşullar bir programı önemli ölçüde karıştırabilir. Örneğin, bir alt pro-
gram, bir matrisin öğelerine 10 referans içeren ifadeleri içerir
mat olarak adlandırılır ve bunlardan herhangi birinde dizin aralık dışı hatası olabilir. Kürk-
dilin dizin aralığı denetimi gerektirmediğini varsayalım. Olmadan
yerleşik dizin aralığı denetimi, bu işlemlerin her birinin
olası bir dizin aralığı hatasını algılamak için koddan önce gelir. Örneğin, düşünün
10 satır ve 20 sütun içeren bir mat öğesine aşağıdaki başvuru :
if (satır >= 0 && satır < 10 && sütun >= 0 && sütun < 20)
toplam += mat[satır][sütun];
Başka
System.out.println("Matta dizin aralığı hatası, satır = " +
satır + " sütun = " + sütun);

Sayfa 654
14.1 Özel Durum Yönetimine Giriş 633
Dilde istisna işlemenin varlığı,
her dizi öğesi erişiminden önce bu tür kontroller için makine kodunu eklemek için piller,
kaynak programı büyük ölçüde kısaltır ve basitleştirir.
İstisna işleme sonuçları için dil desteğinin bir başka avantajı,
istisna yayılımı İstisna yayılımı, bir istisnanın ortaya çıkmasına izin verir
dinamik veya statik olarak başka bir birimde işlenecek bir program birimi
soy. Bu, herhangi bir sayıda tek bir istisna işleyicisinin kullanılmasına izin verir.
farklı program birimleri Bu yeniden kullanım, geliştirmede önemli tasarruflar sağlayabilir.
maliyet, program boyutu ve program karmaşıklığı.
İstisna işlemeyi destekleyen bir dil, kullanıcılarını
Programın yürütülmesi sırasında meydana gelebilecek tüm olayları ve bunların nasıl gerçekleştiğini
ele alınabilir. Bu yaklaşım, böyle bir olasılığı düşünmemekten çok daha iyidir.
ve hiçbir şeyin ters gitmeyeceğini umarak. Bu avantaj, ilgili
tüm olası değerler için eylemleri dahil etmek için çoklu seçici bir yapı gerektirmesi
Ada tarafından gerektiği gibi kontrol ifadesinin.
Son olarak, hatalı olmayan ancak
olağandışı durumlar, istisna işleme ile basitleştirilebilir ve hangi durumlarda
program yapısı onsuz aşırı dolambaçlı hale gelebilir.
14.1.2 Tasarım Sorunları
Şimdi bir istisna işleme sistemi için bazı tasarım konularını inceliyoruz
bir programlama dilinin parçası olduğunda. Böyle bir sistem her ikisine de izin verebilir.
önceden tanımlanmış ve kullanıcı tanımlı istisnalar ve istisna işleyicileri. Bunu not et
önceden tanımlanmış istisnalar dolaylı olarak ortaya çıkarken, kullanıcı tanımlı istisnalar
açıkça kullanıcı kodu tarafından yükseltilmelidir. Aşağıdaki iskelet alt pro-
örtük olarak yükseltilmiş bir istisna işleme mekanizması içeren gram
istisna:
geçersiz örnek() {
. . .
ortalama = toplam / toplam;
. . .
dönüş ;
/* İstisna işleyicileri */
ne zaman zero_divide {
ortalama = 0;
printf("Hata–bölen (toplam) sıfırdır\n");
}
. . .
}
Dolaylı olarak yükseltilen sıfıra bölme istisnası, kontrolün
uygun işleyiciye aktarılır ve daha sonra yürütülür.
İstisna işleme için ilk tasarım sorunu, bir istisnanın nasıl oluştuğudur.
rence bir istisna işleyicisine bağlıdır. Bu sorun iki farklı

Sayfa 655
634
Bölüm 14 İstisna İşleme ve Olay İşleme
seviyeler. Birim düzeyinde, aynı istisnanın nasıl olduğu sorusu vardır.
bir birimde farklı noktalarda yükseltilen farklı işleyicilere bağlanabilir
birim. Örneğin, örnek alt programda, bir
bir olayla başa çıkmak için yazılmış gibi görünen sıfıra bölme istisnası
belirli bir ifadede (gösterilen) sıfıra bölmenin varlığı. Ama varsayalım
işlev, bölme işleçleriyle birlikte birkaç başka ifade içerir. İçin
bu operatörler, bu işleyici muhtemelen uygun olmaz. Yani, olmalı
belirli ifadelerle ortaya çıkabilecek istisnaları bağlamanın mümkün olması
aynı istisna birçok kişi tarafından gündeme getirilebilse de, belirli işleyicilere
farklı ifadeler.
Daha yüksek bir düzeyde, bağlayıcı soru, istisna olmadığında ortaya çıkar.
özel durumun ortaya çıktığı birime yerel işleyici. Bu durumda lan-
guage tasarımcısı, istisnayı diğer bazılarına yaymaya karar vermelidir.
birim ve eğer öyleyse, nerede. Bu yayılma nasıl gerçekleşir ve ne kadar ileri gider?
istisna işleyicilerinin yazılabilirliği üzerinde önemli bir etkiye sahiptir. Örneğin,
işleyicilerin yerel olması gerekiyorsa, uygun olan birçok işleyici yazılmalıdır.
Programın hem yazılmasını hem de okunmasını sağlar. Diğer taraftan, başka bir açıdan
el, istisnalar yayılırsa, tek bir işleyici işleyebilir
birkaç program biriminde ortaya çıkan aynı istisna,
işleyicinin birinin tercih edeceğinden daha genel olmasını gerektirir.
Bir istisnanın bir istisnaya bağlanmasıyla ilgili bir sorun
istisna işleyici, istisna hakkındaki bilgilerin olup olmadığıdır.
işleyicinin kullanımına sunulmuştur.
Bir istisna işleyicisi yürütüldükten sonra, her iki kontrol de
programda işleyici kodunun dışında bir yere veya
program yürütme basitçe sonlandırılabilir. Biz buna sorgu-
işleyicinin yürütülmesinden sonra kontrolün sürdürülmesi veya basitçe
devamı . Sonlandırma açıkçası en basit seçimdir ve
birçok hata istisna koşulunda, en iyisi. Ancak, diğerlerinde
durumlar, özellikle olağandışı ancak hatalı olmayan durumlarla ilgili olanlar
önemli olaylar, devam eden yürütme seçimi en iyisidir. Bu
tasarıma yeniden başlatma denir . Bu durumlarda, bazı sözleşmeler
yürütmenin nerede devam edeceğini belirlemek için seçilmelidir.
İstisnayı ortaya çıkaran ifade olabilir, devlet-
istisnayı ortaya çıkaran ifadeden sonra veya muhtemelen
başka bir birim. Ortaya çıkan ifadeye geri dönme seçeneği
istisna iyi gibi görünebilir, ancak
hata istisnası, yalnızca işleyici bir şekilde yapabiliyorsa yararlıdır
istisnaya neden olan değerleri veya işlemleri değiştirmek için
yükseltilecek. Aksi takdirde, istisna basitçe yeniden oluşturulacaktır. bu
bir hata istisnası için gerekli değişiklik genellikle çok farklıdır.
tahmin etmek hayali. Bununla birlikte, mümkün olduğunda bile, bir
ses alıştırması. Programın semptomunu kaldırmasına izin verir.
nedeni ortadan kaldırmadan bir sorun.
İstisnaların işleyicilere ve bağlayıcılara bağlanmasıyla ilgili iki konu
geçiş Şekil 14.1'de gösterilmektedir.
tarih notu
PL/I (ANSI, 1976) öncülük etti
kullanıcıya izin verme kavramı
doğrudan dahil edilecek programlar
istisna işlemede. bu
dil, kullanıcının yapmasına izin verdi
için istisna işleyicileri yaz
dil tanımlı uzun liste
istisnalar. Ayrıca, PL/I
kavramını tanıttı
kullanıcı tanımlı istisnalar,
programların oluşturulmasına izin ver
yazılım tarafından algılanan istisnalar.
Bu istisnalar aynı
için kullanılan mekanizmalar
yerleşik istisnalar.
PL/I tasarlandığından beri, bir
önemli miktarda iş var
alternatif tasarlamak için yapıldı
istisna işleme yöntemleri.
Özellikle, CLU (Liskov ve diğerleri,
1984), Mesa (Mitchell ve diğerleri,
1979), Ada, ORTAK LISP
(Steele, 1990), ML (Milner
et al., 1990), C++, Modula-3
(Cardelli ve diğerleri, 1989), Eiffel,
Java ve C# istisna içerir-
elleçleme tesisleri.

Sayfa 656
14.1 Özel Durum Yönetimine Giriş 635
İstisna işleme dahil edildiğinde, bir alt programın yürütülmesi
iki şekilde sınanır: yürütülmesi tamamlandığında veya bir sorunla karşılaştığında.
istisna. Bazı durumlarda, bazı hesaplamaları tamamlamak gerekir.
alt program yürütmesinin nasıl sonlandırıldığına bakılmaksızın. Böyle belirtme yeteneği
bir hesaplamaya sonlandırma denir . Sonlandırmayı destekleyip desteklememe seçimi
tion açıkça istisna işleme için bir tasarım sorunudur.
Diğer bir tasarım sorunu şudur: Kullanıcıların istisna tanımlamasına izin veriliyorsa
Bu istisnalar nasıl belirlenir? Her zamanki cevap, bunu istemektir.
bulundukları program birimlerinin şartname bölümlerinde beyan edilirler.
yükseltilebilir. Bildirilen bir istisnanın kapsamı, genellikle
bildirimi içeren program birimi.
Bir dilin önceden tanımlanmış istisnalar sağlaması durumunda, diğer birkaç
tasarım sorunları takip eder. Örneğin, dil çalışma zamanı sistemi şunları sağlamalı mı?
yerleşik istisnalar için varsayılan işleyiciler veya kullanıcının gerekli olması gerekir
tüm istisnalar için işleyiciler yazmak için? Başka bir soru, önceden tanımlanmış olup olmadığıdır.
istisnalar, kullanıcı programı tarafından açıkça ortaya çıkarılabilir. Bu kullanım olabilir
kullanıcının yazılım tarafından algılanabilen durumlar varsa kullanışlıdır.
önceden tanımlanmış bir işleyici kullanmayı sever.
Başka bir sorun, donanım tarafından algılanabilen hataların aşağıdakiler tarafından ele alınıp alınamayacağıdır.
kullanıcı programları Değilse, tüm istisnalar açıkça yazılım tarafından algılanabilir. ilgili
soru, önceden tanımlanmış herhangi bir istisna olup olmadığıdır. önceden tanımlanmış
istisnalar, donanım veya sistem yazılımı tarafından dolaylı olarak ortaya çıkar.
Son olarak, önceden tanımlanmış veya önceden tanımlanmış istisnaların olup olmadığı sorusu vardır.
kullanıcı tanımlı, geçici veya kalıcı olarak devre dışı bırakılabilir. Bu soru
Şekil 14.1
İstisna işleme kontrol akışı
başlamak
son;
başlamak
ne zaman …
ne zaman …
ne zaman …
başlamak
bazı açıklamalar;
son;
son;
başlamak
son;
?
?
Sonlandırma
Ör cep tion t o elle
l e r b ind
i N g
Cı- o , n ti n
u t ben o
n
Yürütme kodu
İstisna işleyicileri
İstisna
yükseltildi

Sayfa 657
636
Bölüm 14 İstisna İşleme ve Olay İşleme
biraz felsefi, özellikle önceden tanımlanmış hata koşulları durumunda.
Örneğin, bir dilin, aşağıdaki durumlarda ortaya çıkan önceden tanımlanmış bir istisnaya sahip olduğunu varsayalım.
bir alt simge aralığı hatası oluşur. Birçoğu, alt simge aralığı hatalarının
her zaman algılanır ve bu nedenle programın algılaması mümkün olmamalıdır.
bu hataların algılanmasını devre dışı bırakın. Diğerleri, alt simge aralığı kontrolünün
üretim yazılımı için çok maliyetli, burada muhtemelen kodun yeterince
hatasız, aralık hataları oluşmamalıdır.
İstisna işleme tasarım sorunları aşağıdaki gibi özetlenebilir:
• İstisna işleyicileri nasıl ve nerede belirtilir ve kapsamları nedir?
• Bir istisna oluşumu, bir istisna işleyicisine nasıl bağlanır?
• Bir istisna hakkındaki bilgiler işleyiciye iletilebilir mi?
• Bir istisna işleyici komutundan sonra yürütme nerede devam ediyor?
icrasını tamamlıyor mu? (Bu, devam veya yeniden başlama sorunudur.)
• Bir tür sonuçlandırma sağlanıyor mu?
• Kullanıcı tanımlı istisnalar nasıl belirlenir?
• Önceden tanımlanmış istisnalar varsa, varsayılan istisna han-
Kendilerini sağlamayan programlar için dlers?
• Önceden tanımlanmış istisnalar açıkça ortaya çıkarılabilir mi?
• Donanım tarafından algılanabilen hatalar, ele alınabilecek istisnalar olarak değerlendiriliyor mu?
• Önceden tanımlanmış istisnalar var mı?
• Önceden tanımlanmış istisnaları devre dışı bırakmak mümkün olmalı mı?
Şu anda istisna işleme olanaklarını inceleyecek bir konumdayız.
üç çağdaş programlama dili.
14.2 Ada'da İstisna İşleme
Ada'da özel durum işleme, daha güvenilir oluşturmak için güçlü bir araçtır
yazılım sistemleri. İstisna işleme tasarımının iyi kısımlarına dayanmaktadır.
istisna işleme ile daha önceki iki dilden - PL/I ve CLU.
14.2.1 İstisna İşleyicileri
Ada istisna işleyicileri genellikle istisnanın içinde bulunabileceği kodda yereldir.
yükseltilebilir (ancak diğer program birimlerine yayılabilirler). Çünkü
bu onlara aynı referans ortamını sağlar;
işleyiciler gerekli değildir ve izin verilmez. Bu nedenle, eğer bir istisna ise
istisnayı ortaya çıkaran birimden farklı bir birimde işleniyor, bilgi yok
istisna hakkında işleyiciye iletilebilir. 3
3. Pek doğru değil. İşleyicinin istisna adını, kısa bir açıklamayı alması mümkündür.
istisnanın durumu ve istisnanın ortaya çıktığı yaklaşık konum.

Sayfa 658
14.2 Ada 637'de İstisna İşleme
İstisna işleyicileri, burada EBNF'de verilen aşağıdaki genel forma sahiptir:
ne zaman istisna_seçim {| istisna_seçim } => ifade_dizisi
Parantezlerin metasemboller olduğunu hatırlayın, bu da içerdikleri şeyin
dışarıda bırakılabilir veya herhangi bir sayıda tekrarlanabilir. İstisna_seçimi şu şekildedir:
istisna_adı | diğerleri
İstisna_adı, bu işleyicinin kastedildiği belirli bir istisnayı belirtir.
işlemek için. İfade dizisi, işleyici gövdesidir. Ayrılmış kelime
diğerleri , işleyicinin adlandırılmamış istisnaları işlemek için tasarlandığını belirtir.
başka herhangi bir yerel işleyicide.
İstisna işleyicileri, bloklara veya alt programların gövdelerine dahil edilebilir.
gramlar, paketler veya görevler. Göründükleri blok veya birimden bağımsız olarak,
işleyiciler, yerleştirilmesi gereken bir istisna maddesi içinde bir araya toplanır.
bloğun veya birimin sonunda. Örneğin, bir istisnanın olağan biçimi
cümlesi aşağıdaki şekilde gösterilmiştir:
başlamak
-- blok veya birim gövdesi --
istisna
zaman EXCEPTION_NAME 1 =>
-- ilk işleyici --
zaman EXCEPTION_NAME 2 =>
-- ikinci işleyici --
-- diğer işleyiciler --
son ;
İşleyicinin göründüğü blokta veya birimde görünebilecek herhangi bir ifade
işleyicide de yasaldır.
14.2.2 İstisnaları İşleyicilere Bağlama
Bir istisna oluşturan blok veya birim bunun için bir işleyici içerdiğinde
istisna, istisna, bu işleyiciye statik olarak bağlıdır. bir istisna ise
belirli bir işleyicisi olmayan bir blokta veya birimde yükseltilir
istisna, istisna başka bir bloğa veya birime yayılır. bu
istisnaların yayılma şekli, programın bulunduğu program varlığına bağlıdır.
istisna oluşur.
Bir prosedürde bir istisna ortaya çıktığında, detaylandırmada olsun ya da olmasın
beyanlarının veya kuruluşunun yürütülmesinde ve prosedürün hiçbir
bunun için işleyici, istisna dolaylı olarak çağıran programa yayılır.
çağrı noktasındaki birim. Bu politika, tasarım felsefesinin bir yansımasıdır.
alt programlardan istisna yayılımının,
kontrol yolu (dinamik atalar), statik atalar aracılığıyla değil.
Bir istisnanın yayıldığı çağrı birimi de
istisna için işleyici yok, yine o birimin arayanına iletilir. Bu

Sayfa 659
638
Bölüm 14 İstisna İşleme ve Olay İşleme
gerekirse dinamik kökü olan ana prosedüre devam eder.
Her Ada programı. Ana prosedüre bir istisna yayılırsa ve bir
işleyici hala bulunamadı, program sonlandırıldı.
İstisna işleme alanında, bir Ada bloğu bir
yürütme bağlandığında üst bloğu tarafından "çağrılan" parametresiz prosedür
trol bloğun ilk ifadesine ulaşır. Bir blokta bir istisna oluşturulduğunda,
bildirimlerinde veya yürütülebilir ifadelerinde ve bloğun işleyicisi yok
bunun için istisna, bir sonraki daha büyük çevreleyen statik kapsama yayılır;
onu "çağıran" koddur. İstisnanın yayıldığı nokta şudur:
meydana geldiği bloğun bitiminden hemen sonra, bu onun “dönüş” noktasıdır.
Bir paket gövdesinde ve paket gövdesinde bir istisna oluşturulduğunda
istisna için işleyicisi yoktur, istisna beyana yayılır.
paket bildirimini içeren birimin tion bölümü. eğer paket
(ayrı olarak derlenen) bir kitaplık birimi olur, program
sonlandırılmış.
Bir görev gövdesinde en dış düzeyde bir istisna oluşursa (iç içe geçmiş bir
blok) ve görev, istisna için bir işleyici içerir, bu işleyici yürütülür.
cuted ve görev tamamlandı olarak işaretlendi. Görevin bir özelliği yoksa
istisna için işleyici, görev basitçe tamamlandı olarak işaretlenir; en
istisna yayılmaz. Bir görevin kontrol mekanizması çok karmaşık
nerede olduğu sorusuna makul ve basit bir cevaba
işlenmeyen istisnalar yayılmalıdır.
Bildirime dayalı bölümün hazırlanması sırasında da istisnalar ortaya çıkabilir.
alt programlar, bloklar, paketler ve görevler. Bu tür istisnalar olduğunda
prosedürlerde, paketlerde ve bloklarda yetiştirilirler, tam olarak yayılırlar
istisna, ilişkili kod bölümünde ortaya çıkmış gibi. Bu durumuda
bir görev, görev tamamlandı olarak işaretlenir, daha fazla detaylandırma gerektirmez
yer ve yerleşik istisna Tasking_Error noktasında yükseltilir
görev için aktivasyon.
14.2.3 Devam
Ada'da, istisna oluşturan tüm birimlerle birlikte bir istisna oluşturan blok veya birim.
istisna yayıldı ama bu işlemedi, her zaman sonlandırıldı.
Denetim, istisnadan sonra hiçbir zaman örtülü olarak yükselten bloğa veya birime geri dönmez
işlenir. Denetim, her zaman geçerli olan istisna yan tümcesinden sonra devam eder.
bir bloğun veya birimin sonunda. Bu, daha yüksek bir seviyeye anında geri dönüşe neden olur
kontrol.
İstisna işleyicisinden sonra yürütmenin nerede devam edeceğine karar verirken
yürütme bir program biriminde tamamlandı, Ada tasarım ekibinin çok az
seçim, çünkü Ada için gereksinimler spesifikasyonu (Departmanı
Defence, 1980a) istisnaları ortaya çıkaran program birimlerinin
devam ettirilebilir veya yeniden başlatılabilir. Ancak, bir blok durumunda, bir ifade olabilir
bir istisna oluşturduktan ve bu istisna işlendikten sonra yeniden denenir. Örneğin,
bir istisna oluşturabilecek bir ifade ve bu istisna için bir işleyici varsayalım
her ikisi de bir döngü içine alınmış bir bloğun içine alınır. Devamındaki

Sayfa 660
14.2 Ada 639'da İstisna İşleme
istenen aralıkta dört tamsayı değeri alan örnek kod segmenti
klavye, bu tür bir yapıyı gösterir:
. . .
type Age_Type , 0..125 aralığıdır;
tip Age_List_Type dizisidir (1..4) arasında Age_Type;
Age_IO paketi yeni Integer_IO (Age_Type);
Age_IO'yu kullanın ;
Age_List : Age_List_Type;
. . .
başlamak
için Age_Count içinde 1..4 döngü
döngü -- istisnalar oluştuğunda tekrarlama için döngü
Hariç_Blk:
start -- özel durum işlemeyi kapsüllemek için bileşik
Put_Line("0,..125 aralığında bir tamsayı giriniz");
Get(Yaş_Listesi(Yaş_Sayısı));
çıkış ;
istisna
Data_Error => olduğunda -- Girdi dizesi bir sayı değil
Put_Line("Geçersiz sayısal değer");
Put_Line("Lütfen tekrar deneyiniz");
Constraint_Error => olduğunda -- Giriş < 0 veya > 125 olduğunda
Put_Line("Girilen sayı aralık dışında");
Put_Line("Lütfen tekrar deneyiniz");
son Except_Blk;
son döngü ; -- girişi tekrarlamak için sonsuz döngünün sonu
-- bir istisna olduğunda
son döngü ; -- 1.4 döngüsünde Age_Count için sonu
. . .
Kontrol, geçerli bir sonuç oluşana kadar yalnızca bloğu içeren iç döngüde kalır.
giriş numarası alınır.
14.2.4 Diğer Tasarım Seçenekleri
Standart pakette tanımlanan dört istisna vardır :
Constraint_Error
Program_Hatası
Depolama_Hatası
Tasking_Error
Bunların her biri aslında bir istisna kategorisidir. Örneğin, istisna
Constraint_Error , bir dizi indisi aralık dışında olduğunda ortaya çıkar.
Aralık kısıtlaması olan sayısal bir değişkende bir aralık hatası olduğunda,

Sayfa 661
640
Bölüm 14 İstisna İşleme ve Olay İşleme
Ayrımcı bir birliktelikte bulunmayan bir kayıt alanına atıfta bulunulursa,
ve diğer birçok durumda.
Standartta tanımlanan istisnalara ek olarak, önceden tanımlanmış diğer paket-
yaşlar diğer istisnaları tanımlar. Örneğin, Ada.Text_IO tanımlar END_ERROR
istisna.
Kullanıcı tanımlı istisnalar, aşağıdaki bildirim formuyla tanımlanır:
istisna_adı_listesi: istisna
Bu tür istisnalar, tam olarak önceden tanımlanmış istisnalar olarak kabul edilir, ancak bunlar
açıkça yükseltilmelidir.
Önceden tanımlanmış istisnalar için varsayılan işleyiciler vardır ve bunların tümü
program sonlandırmada.
İstisnalar, aşağıdakileri içeren yükseltme deyimi ile açıkça ortaya çıkar .
Genel form
[istisna_adı] yükselt
Bir istisna belirtmeden bir yükseltme ifadesinin görünebileceği tek yer
tion bir istisna işleyicisi içindedir. Bu durumda, aynı istisnayı yeniden oluşturur.
işleyicinin yürütülmesine neden oldu. Bu, yayılma etkisine sahiptir.
Daha önce belirtilen yayılma kurallarına göre istisna. Bir zam bir in
istisna işleyicisi, bir hata mesajı yazdırmak istendiğinde yararlıdır.
bir istisna oluşturulur ancak istisnayı başka bir yerde işleyin.
Bir Ada pragma , derleyiciye yönelik bir yönergedir. Belirli çalışma zamanı kontrolleri
Yerleşik istisnaların parçaları, Ada programlarında aşağıdakiler kullanılarak devre dışı bırakılabilir:
engelle Pragma , basit bir şeklidir
pragma Bastırma( check_name )
check_name, belirli bir istisna denetiminin adıdır. Örnekleri
bu tür kontroller bu bölümün ilerleyen kısımlarında verilmektedir.
Engelle Pragma beyan bölümlerde sadece görünebilir. Ne zaman
göründüğünde, belirtilen kontrol ilgili blokta askıya alınabilir veya
bildirim bölümünün bir parçası olduğu program birimi. Açık zamlar değil
Supress'ten etkilenir . Gerekli olmamasına rağmen, çoğu Ada derleyicisi
ment engelle pragma .
Bastırılabilen kontrol örnekleri şunlardır: Index_
Check ve Range_Check normalde yapılan kontrollerden ikisini belirtir
bir Ada programında; Index_Check , dizi alt simge aralığı denetimine atıfta bulunur;
Range_Check , bir değerin aralığı gibi şeyleri kontrol etmek anlamına gelir.
bir alt tür değişkenine atanır. Ya olursa index_check veya Range_Check olduğu
ihlal edildi, Constraint_Error yükseltildi. Division_Check ve Taşma_
Kontrol , Numeric_Error ile ilişkili bastırılabilir kontrollerdir . Takip-
ing Pragma devre dışı bırakıyorsa dizi indis aralığı denetimi:
pragma Bastırma(Index_Check);
Adlandırılmış kontrolün daha fazla olmasını sağlayan bir Bastırma seçeneği vardır.
belirli nesneler, türler, alt türler ve program birimleriyle sınırlıdır.

Sayfa 662
14.2 Ada 641'de İstisna İşleme
14.2.5 Bir Örnek
Aşağıdaki örnek program, istisna elinin bazı basit kullanımlarını göstermektedir.
Ada'dakiler. Program, girdi notlarının dağılımını hesaplar ve yazdırır.
bir dizi sayaç kullanarak. Girdi, bir not ile sonlandırılan bir notlar dizisidir.
bir Constraint_Error istisnası oluşturan negatif sayı, çünkü
notlar Doğal tiptir (negatif olmayan tam sayılar). 10 kategori var
dereceler (0–9, 10–19, . . . , 90–100). Notların kendileri hesaplamak için kullanılır
her not kategorisi için bir sayaç dizisine indeksler. Geçersiz Giriş
dereceler, sayaç dizisindeki indeksleme hatalarını yakalayarak tespit edilir. bir sınıf
100, not dağılımının hesaplanmasında özeldir çünkü kat-
11 (90,
91, . . . , 100). (B veya C'den daha fazla olası A notu olduğu gerçeği
öğretmenlerin cömertliğinin kesin kanıtıdır.) 100 notu da
geçersiz giriş verileri için kullanılan aynı özel durum işleyicisinde işlenir.
-- Not Dağılımı
-- Girdi: Temsil eden tamsayı değerlerinin bir listesi
--
notlar, ardından negatif bir sayı
-- Çıktı: Yüzde olarak notların dağılımı
--
0-9, 10-19 kategorilerinin her biri, . . .,
--
90-100.
ile Ada.Text_IO, Ada.Integer.Text_IO;
Ada.Text_IO, Ada.Integer.Text_IO kullanın ;
prosedür Grade_Distribution olduğu
Sıklık: dizisi (1.10) arasında bir tamsayı: = ( diğerleri => 0);
Yeni_Sınıf: Doğal;
dizin,
sınır_1,
Limit_2 : Tamsayı;
başlamak
Derece_Döngüsü:
döngü
start -- Negatif girdi istisnası için bir blok
Get(New_Grade);
istisna
Constraint_Error => olduğunda -- negatif giriş için
Grade_Loop'tan çıkın ;
son ; -- negatif giriş bloğunun sonu
Dizin := Yeni_Sınıf / 10 + 1;
start -- Alt simge aralığı işleyicisi için bir blok
Frekans(İndeks) := Frekans(İndeks) + 1;
istisna
-- Dizin aralığı hataları için
Constraint_Error => olduğunda
Eğer NEW_GRADE 100 = Daha sonra
Frekans(10) := Frekans(10) + 1;

Sayfa 663
642
Bölüm 14 İstisna İşleme ve Olay İşleme
Başka
Put("HATA -- yeni not: ");
Put(New_Grade);
Put("aralık dışı");
Yeni hat;
eğer sona erer ;
son ; -- alt simge aralığı bloğunun sonu
son döngü ;
-- Çıktı üret
Put("Sınır Limitleri");
Yeni hat; Yeni hat;
için Endeksinde içinde 0..9 döngü
Limit_1 := 10 * İndeks;
Limit_2 := Limit_1 + 9;
eğer Endeksi 9 = o
Limit_2 := 100;
eğer sona erer ;
koy(Limit_1);
koy(Limit_2);
Put(Freq(İndeks + 1));
Yeni hat;
son döngü ; -- 0..9'daki İndeks için . . .
son Grade_Distribution;
Geçersiz girdi notlarını işleyecek kodun kendi yerel bloğunda olduğuna dikkat edin.
Bu, programın bu tür istisnalar işlendikten sonra devam etmesine izin verir.
klavyeden değerleri okuyan önceki örneğimizde. için işleyici
negatif giriş de kendi bloğundadır. Bu engellemenin nedeni kısıtlamaktır.
negatif tarafından yükseltildiğinde Constraint_Error işleyicisinin kapsamı
giriş.
14.2.6 Değerlendirme
Diğer bazı dil yapılarında olduğu gibi, Ada'nın istisna tasarımı
işleme, en azından tasarımı sırasında bir fikir birliğini temsil eder.
(1970'lerin sonu ve 1980'lerin başı), konuyla ilgili fikirler. Bir süredir Adana
istisna işlemeyi içeren tek yaygın olarak kullanılan dildi.
Ada'nın özel durum işlemesiyle ilgili birkaç sorun var. Bir sorun
istisnaların bir dış ortama yayılmasına izin veren yayılma modeli
istisnanın görünmediği kapsam. Ayrıca, her zaman mümkün değildir.
yayılan istisnaların kaynağını belirler.
Diğer bir sorun, görevler için istisna işlemenin yetersizliğidir. İçin
örneğin, bir istisna oluşturan ancak onu işlemeyen bir görev basitçe ölür.
Son olarak, Ada 95'e nesne yönelimli programlama desteği eklendiğinde,
istisna işlemesi, yeni yapılarla başa çıkmak için genişletilmedi. İçin
örneğin, bir sınıfın birkaç nesnesi oluşturulduğunda ve bir blokta kullanıldığında ve

Sayfa 664
14.3 C++ 643'te Özel Durum İşleme
bunlardan biri bir istisna yayıyor, hangisinin olduğunu belirlemek imkansız
istisnayı gündeme getirdi.
Ada'nın istisna işleme sorunları Romanovsky'de tartışılıyor
ve Sanden (2001).
14.3 C++'da İstisna İşleme
C++'ın istisna işlemesi, ANSI C++ standardizasyonu tarafından kabul edildi
Komite 1990'da ve ardından C++ uygulamalarına girmenin yolunu buldu.
Tasarım kısmen CLU, Ada ve ML'nin istisna işlemesine dayanmaktadır.
C++'ın istisna işlemesi ile Ada'nınki arasındaki önemli bir fark
C++'da önceden tanımlanmış istisnaların olmamasıdır (standart kitaplığı dışında).
i). Bu nedenle, C++'da istisnalar kullanıcı veya kitaplık tarafından tanımlanır ve açıkça ortaya çıkar.
14.3.1 İstisna İşleyicileri
Bölüm 14.2'de Ada'nın program birimlerini veya bloklarını kullanarak
istisna işleyicileri için kapsam. C++ tanıtılan özel bir yapı kullanır
ayrılmış kelime ile bu amaç için deneyin . Bir try yapısı bir komut içerir.
pound ifadesi, try yan tümcesi ve özel durum işleyicilerinin bir listesi olarak adlandırılır . bu
bileşik ifade, aşağıdaki işleyicilerin kapsamını tanımlar. Genel
bu yapının formu
denemek {
//** Bir istisna oluşturabilecek kod
}
catch ( resmi parametre ) {
//** Bir işleyici gövdesi
}
. . .
catch ( resmi parametre ) {
//** Bir işleyici gövdesi
}
Her yakalama işlevi bir istisna işleyicisidir. Bir yakalama işlevi şunları yapabilir:
resmi bir parametreye benzeyen yalnızca tek bir resmi parametreye sahip
üç nokta olma olasılığı da dahil olmak üzere C++'daki bir işlev tanımında
( . . . ). Üç nokta biçimsel parametresi olan bir işleyici, tümünü yakalama işleyicisidir; o
uygun bir işleyici bulunmazsa, ortaya çıkan herhangi bir istisna için yürürlüğe girer. bu
biçimsel parametre de gibi, çıplak bir tür belirteci olabilir şamandıra A'daki gibi,
fonksiyon prototipi. Böyle bir durumda, biçimsel parametrenin tek amacı,
işleyiciyi benzersiz bir şekilde tanımlanabilir hale getirmek için. İstisna hakkında bilgi verildiğinde-
işleyiciye iletilecektir, resmi parametre bir değişken içerir
Bu amaçla kullanılan isim. Çünkü parametrenin sınıfı

Sayfa 665
644
Bölüm 14 İstisna İşleme ve Olay İşleme
herhangi bir kullanıcı tanımlı sınıf, parametre olduğu kadar çok veri üyesi içerebilir
gerekli. İşleyicilere bağlama istisnaları Bölüm 14.3.2'de tartışılmıştır.
C++'da istisna işleyicileri herhangi bir C++ kodunu içerebilir.
14.3.2 İstisnaları İşleyicilere Bağlama
C++ istisnaları yalnızca , genel özelliği olan throw açık ifadesi tarafından oluşturulur.
EBNF'deki form
[ ifade ] atmak ;
Buradaki parantezler, ifadenin şu şekilde olduğunu belirtmek için kullanılan metasembollerdir.
isteğe bağlı. İşlenensiz bir atış yalnızca bir işleyicide görünebilir. Ne zaman
orada göründüğünde, daha sonra başka bir yerde ele alınan istisnayı yeniden ortaya çıkarır. Bu
etkisi tam olarak Ada'daki gibidir.
Atma ifadesinin türü , belirli işleyiciyi seçer;
kursun "eşleşen" tip bir resmi parametresi olmalıdır. Bu durumda eşleştirme
şu anlama gelir: T , const T , T& türünde resmi bir parametreye sahip bir işleyici
( T türünde bir nesneye başvuru ) veya const T& ile bir atışla eşleşir
T tipinin ifadesi . T'nin bir sınıf olması durumunda , parametresi
T tipi veya T eşleşmelerinin atası olan herhangi bir sınıftır . Daha fazla uyum var
bir atış ifadesinin resmi bir parametreyle eşleştiği, ancak
burada anlatılmazlar.
Try yan tümcesinde ortaya çıkan bir istisna , yürütmenin hemen sona ermesine neden olur
bu try yan tümcesindeki kodun . Eşleşen bir işleyici araması şu şekilde başlar:
try yan tümcesini hemen takip eden işleyiciler . Eşleştirme işlemi yapılır
bir eşleşme bulunana kadar işleyicilerde sırayla. Bunun anlamı, eğer başka varsa
eşleşme tam olarak eşleşen bir işleyiciden önce gelir, tam olarak eşleşen işleyici
kullanılamaz. Bu nedenle, belirli istisnalar için işleyiciler en üstte yer alır.
liste, ardından daha genel işleyiciler. Son işleyici genellikle
herhangi bir istisnayla eşleşen bir üç nokta ( . . . ) resmi parametresi. Bu
tüm istisnaların yakalandığını garanti eder.
Bir try yan tümcesinde bir istisna ortaya çıkarsa ve eşleşen bir işleyici yoksa
bu try yan tümcesiyle ilişkiliyse , istisna yayılır. Eğer deneyin maddesi
başka bir try yan tümcesinin içine yerleştirilmişse , istisna işleyicilere yayılır
dış try yan tümcesi ile ilişkili . Ekteki try cümleciklerinden hiçbiri sonuç vermezse
eşleşen bir işleyici, istisna, işlevin arayanına iletilir
hangisinde yetiştirildi. İşlev çağrısı bir try yan tümcesinde değilse ,
istisna, bu işlevin arayanına yayılır. Eşleşen bir işleyici bulunamazsa
programda bu yayılma işlemi aracılığıyla varsayılan işleyici çağrılır.
Bu işleyici, Bölüm 14.3.4'te daha ayrıntılı olarak tartışılmaktadır.
14.3.3 Devam
Bir işleyici yürütmesini tamamladıktan sonra, kontrol ilk ifadeye akar.
try yapısını takiben (son işleyiciden hemen sonraki ifade
öğesi olduğu işleyiciler sırasında). Bir işleyici yeniden yükseltebilir

Sayfa 666
C ++ Taşıma 14.3 durum 645
bir istisna, ifadesiz bir atış kullanmak, bu durumda istisna-
propagandası yapılır.
14.3.4 Diğer Tasarım Seçenekleri
Bölüm 14.1.2'de özetlenen tasarım konuları açısından, istisna han-
C++'ın dling'i basittir. Orada sadece kullanıcı tanımlı istisnalar ve bunlar
belirtilmemiş (yine de yeni sınıflar olarak bildirilebilirler). bir varsayılan var
istisna işleyicisi, beklenmeyen , tek eylemi pro-
gram. Bu işleyici, program tarafından yakalanmayan tüm istisnaları yakalar. Olabilir
kullanıcı tanımlı bir işleyici ile değiştirilir. Değiştirme işleyicisi bir işlev olmalıdır.
void döndüren ve parametre almayan tion . Değiştirme işlevi
adını set_terminate öğesine atayarak ayarlayın . İstisnalar devre dışı bırakılamaz.
Bir C++ işlevi, istisna türlerini ( atma türleri) listeleyebilir.
ifadeler) yükseltebilir. Bu özel amaçlı sözcük ekleyerek yapılır atışı ,
işlev başlığına bu türlerin parantez içindeki bir listesi gelir. Örneğin,
int eğlence() fırlatma ( int , char * ) { . . . }
fun işlevinin int ve char * türünde istisnalar oluşturabileceğini belirtir, ancak
başka kimse. Fırlatma yan tümcesinin amacı , işlevin ne olduğunu kullanıcılara bildirmektir.
işlev tarafından istisnalar ortaya çıkabilir. Atmak fıkra yürürlükte kısıtlayıcı bir etken olduğunu
işlev ve onu arayanlar arasındaki yol. Başka bir istisna olmadığını garanti eder
fonksiyonda yükseltilecektir. İşlev listelenmemiş bir istisna atarsa,
program sonlandırılacaktır. Derleyicinin atma cümleciklerini yok saydığına dikkat edin .
Fth yan tümcesindeki türler sınıflarsa, işlev yükseltebilir
listelenen sınıflardan türetilen herhangi bir istisna. Bir işlev başlığında bir
atmak maddesini ve listelenmeyen bir özel durum atmak maddesi ve
orada listelenen bir sınıftan türetilmez, varsayılan işleyici çağrılır. Bunu not et
bu hata derleme zamanında tespit edilemez. Listedeki türlerin listesi,
boş olun, bu, işlevin herhangi bir istisna oluşturmayacağı anlamına gelir. yoksa
başlığa belirtimi atarsanız , işlev herhangi bir istisna oluşturabilir. bu
list, işlevin türünün bir parçası değil.
Bir işlev, atma yan tümcesi olan bir işlevi geçersiz kılarsa, geçersiz kılma
işlev , geçersiz kılınandan daha fazla istisna dışında bir atma yan tümcesine sahip olamaz
işlev.
C++'ın önceden tanımlanmış istisnaları olmamasına rağmen, standart kitaplıklar şunları tanımlar:
ve kitaplık tarafından atılabilen out_of_range gibi istisnalar atın
matematik kitaplığı tarafından atılabilen kapsayıcı sınıfları ve overflow_error
fonksiyonlar.
14.3.5 Bir Örnek
Aşağıdaki örnek, istisna işlemenin amacına ve kullanımına sahiptir
Bölüm 14.2.5'te gösterilen Ada programı gibi. Bir dağıtım üretir
10 kategori için bir dizi sayaç kullanarak notları girin. Yasadışı notlar

Sayfa 667
646
Bölüm 14 İstisna İşleme ve Olay İşleme
artırmada kullanılan geçersiz abonelikler kontrol edilerek tespit edilir.
seçilen sayaç
// Not Dağılımı
// Giriş: Temsil eden tamsayı değerlerinin bir listesi
//
notlar, ardından negatif bir sayı
// Çıktı: Yüzde olarak notların dağılımı
//
0-9, 10-19 kategorilerinin her biri, . . .,
//
90-100.
#include <iostream>
int main() { //* Herhangi bir istisna oluşturulabilir
int yeni_grade,
dizin,
sınır_1,
sınır_2,
sıklık[10] = {0,0,0,0,0,0,0,0,0,0};
// Verinin sonunu ele alacak istisna tanımı
sınıf NegativeInputException {
halka açık:
NegativeInputException() { //* Yapıcı
cout << "Giriş verilerinin sonuna ulaşıldı" << endl;
} //** yapıcının sonu
} //** NegativeInputException sınıfının sonu
denemek {
while ( doğru ) {
cout << "Lütfen bir not girin" << endl;
if ((cin >> new_grade) < 0) //* Veri sonu
NegativeInputException() atmak ;
dizin = new_grade / 10;
{ dene {
if (indeks > 9)
new_grade atmak ;
sıklık[indeks]++;
} //* iç deneme bileşiğinin sonu
catch ( int notu) { //* İndeks hataları için işleyici
if (derece == 100)
sıklık[9]++;
Başka
cout << "Hata -- yeni not: " << not
<< " aralık dışında" << endl;
} //* yakalamanın sonu(int notu)
} //* iç try-catch için bloğun sonu
çift
} //* süre sonu (1)
} //* dış try bloğunun sonu

Sayfa 668
14.4 Java 647'de İstisna İşleme
catch (NegativeInputException& e) { //**İşleyici için
//** negatif giriş
cout << "Sınırları Sınırlar" << endl;
for (indeks = 0; dizin < 10; dizin++) {
limit_1 = 10 * dizin;
limit_2 = limit_1 + 9;
if (indeks == 9)
limit_2 = 100;
cout << limit_1 << limit_2 << sık[indeks] << endl;
} //* for sonu (indeks = 0)
} //* yakalama sonu (NegativeInputException& e)
} //* main'in sonu
Bu program, C++ istisna işlemenin mekaniğini göstermek içindir. Not
dizin aralığı istisnasının genellikle dizin oluşturmayı aşırı yükleyerek C++ 'da işlendiğini
doğrudan tespit edilmesinden ziyade istisnayı ortaya çıkarabilecek bir işlemdir.
Örneğimizde kullanılan seçim yapısıyla indeksleme işlemi.
14.3.6 Değerlendirme
Bazı yönlerden, C++ istisna işleme mekanizması aşağıdakine benzer:
Ada. Örneğin, işlevlerdeki işlenmeyen istisnalar,
işlevin arayanı. Ancak, başka şekillerde C++ tasarımı oldukça farklıdır:
İşlenebilecek önceden tanımlanmış donanım tarafından algılanabilen istisnalar yoktur
kullanıcı tarafından ve istisnalar adlandırılmaz. İstisnalar, han-
biçimsel parametrenin atlanabileceği bir parametre türü aracılığıyla dlers.
Bir işleyicinin biçimsel parametresinin türü, aşağıdaki koşulu belirler:
buna denir, ancak doğanın doğası ile hiçbir ilgisi olmayabilir.
yükseltilmiş istisna Bu nedenle, istisnalar için önceden tanımlanmış türlerin kullanılması kesinlikle
okunabilirliği desteklemez. İstisnalar için sınıfları tanımlamak çok daha iyidir
tanımlamak için kullanılabilecek anlamlı bir hiyerarşide anlamlı isimlerle
istisnalar. İstisna parametresi, hakkında bilgi iletmek için bir yol sağlar.
istisna işleyicisi için bir istisna.
14.4 Java'da İstisna İşleme
13. Bölümde, Java örnek programı istisna kullanımını içerir.
küçük bir açıklama ile işleme. Bu bölüm, Java'nın ayrıntılarını açıklar.
istisna işleme yetenekleri.
Java'nın istisna işlemesi C++'ınkine dayanmaktadır, ancak şu şekilde tasarlanmıştır:
daha çok nesne yönelimli dil paradigması ile uyumludur. Ayrıca, Java
tarafından dolaylı olarak ortaya çıkan önceden tanımlanmış istisnalar koleksiyonunu içerir.
Java Sanal Makinesi (JVM).

Sayfa 669
648
Bölüm 14 İstisna İşleme ve Olay İşleme
14.4.1 İstisna Sınıfları
Tüm Java istisnaları, Throw'un soyundan gelen sınıfların nesneleridir.
yetenekli sınıf. Java sistemi, önceden tanımlanmış iki istisna sınıfı içerir.
Throwable : Error and Exception'ın alt sınıflarıdır . Hata sınıfı ve
torunları, Java çalışma zamanı sistemi tarafından atılan hatalarla ilgilidir.
öbek belleğin tükenmesi gibi. Bu istisnalar asla atılmaz
kullanıcı programları tarafından ve asla orada ele alınmamalıdır. İki tane
Sistem tanımlı doğrudan soyundan özel durum : RuntimeException ve
IOİstisna . Adından da anlaşılacağı gibi, bir hata oluştuğunda IOException atılır.
tümü metot olarak tanımlanan bir girdi veya çıktı işleminde meydana geldi.
Java.io paketinde tanımlanan çeşitli sınıflardaki ods .
RuntimeException öğesinin soyundan gelen önceden tanımlanmış sınıflar vardır .
Çoğu durumda, RuntimeException (JVM 4 tarafından ) bir kullanıcı pro-
gram hata veriyor. Örneğin, ArrayIndexOutOfBoundsException ,
java.util içinde tanımlanan , aşağı doğru inen yaygın olarak atılan bir istisnadır.
dan RuntimeException . Yaygın olarak atılan başka bir istisna
dan alçalır RuntimeException olan NullPointer İstisna .
Kullanıcı programları kendi istisna sınıflarını tanımlayabilir. içindeki kongre
Java, kullanıcı tanımlı istisnaların Exception öğesinin alt sınıfları olmasıdır .
14.4.2 İstisna İşleyicileri
Java'nın istisna işleyicileri, C++ ile aynı forma sahiptir, bunun dışında
her yakalamanın bir parametresi olmalı ve parametrenin sınıfı bir olmalıdır.
önceden tanımlanmış Throwable sınıfının soyundan gelir .
Java'daki try yapısının sözdizimi , aşağıdakiler dışında tam olarak C++ ile aynıdır.
Son olarak maddesi Bölüm 14.4.6 tarif edilmiştir.
14.4.3 İşleyicilere Bağlayıcı İstisnalar
Bir istisna atmak oldukça basittir. İstisna sınıfının bir örneği
throw ifadesinin işleneni olarak verilir . Örneğin, tanımladığımızı varsayalım
olarak MyException adlı bir istisna
class MyException , İstisna'yı genişletir {
genel MyException() {}
public MyException(Dize mesajı) {
süper (mesaj);
}
}
Bu istisna ile atılabilir
4. Java belirtimi ayrıca JIT derleyicilerinin bu istisnaları algılamasını ve
RunTimeException oluştuğunda.

Sayfa 670
14.4 Java 649'da İstisna İşleme
yeni MyException() atmak ;
Atış için istisna örneğinin oluşturulması yapılabilir
gibi , throw ifadesinden ayrı olarak
MyException myExceptionObject = yeni MyException();
. . .
myExceptionObject atmak ;
Yeni sınıfımıza dahil ettiğimiz iki kurucudan birinin
parametresi ve diğerinin, kendisine gönderdiği bir String nesne parametresi vardır.
onu görüntüleyen üst sınıf ( İstisna ). Bu nedenle, yeni istisnamız
ile atılmak
yeni MyException atmak
("hatanın yerini belirten bir mesaj");
Java'da istisnaların işleyicilere bağlanması, C++'ınkine benzer.
Bir try yapısının bileşik ifadesinde bir istisna atılırsa , bu
denemenin hemen ardından ilk işleyiciye ( yakalama işlevi) bağlanır
parametresi atılan nesneyle aynı sınıf olan yan tümce veya bir
bunun için. Eşleşen bir işleyici bulunursa, atış ona bağlanır ve
uygulanmış.
İstisnalar ele alınabilir ve daha sonra bir atış dahil edilerek yeniden atılabilir
işleyicinin sonunda işlenen olmadan ifade. Yeni atılan
istisna , orijinal olduğu yerde aynı denemede ele alınmayacaktır
atılır, bu nedenle döngü bir endişe değildir. Bu yeniden atma genellikle şu durumlarda yapılır:
bazı yerel eylemler yararlıdır, ancak ekteki bir try yan tümcesi tarafından daha fazla ele alınması
veya arayanda bir try yan tümcesi gereklidir. Bir işleyicide bir throw ifadesi
kontrolü aktaran dışında bir istisna da atabilir
bu işleyiciye.
Bir try yan tümcesinde oluşturulabilecek istisnaların her zaman
bir yöntemle işlenirse, tüm istisnalarla eşleşen özel bir işleyici yazılabilir.
türetilen ları özel durum , sadece, bir ile işleyici tanımlayarak
İstisna türü parametresi, olduğu gibi
catch (ExceptiongeneralObject) {
. . .
}
Bir sınıf adı her zaman kendisiyle veya herhangi bir üst sınıfla eşleştiğinden, herhangi bir sınıf
elde edilen özel durum stoktaki özel durum . Tabii ki, böyle bir istisna
işleyici her zaman işleyici listesinin sonuna yerleştirilmelidir, çünkü
içinde bulunduğu try yapısında onu takip eden herhangi bir işleyicinin kullanımını engelle
görünür. Bu, eşleşen bir işleyici aramasının sıralı olması nedeniyle oluşur,
ve bir eşleşme bulunduğunda arama sona erer.

Sayfa 671
650
Bölüm 14 İstisna İşleme ve Olay İşleme
14.4.4 Diğer Tasarım Seçenekleri
Program yürütme sırasında, Java çalışma zamanı sistemi, programın sınıf adını depolar.
Programdaki her nesne. getClass yöntemi , bir
kendisi getName ile alınabilen sınıf adını saklayan nesne
yöntem. Böylece, gerçek parametrenin sınıfının adını alabiliriz.
işleyicinin yürütülmesine neden olan throw ifadesinden. işleyici için
daha önce gösterildiği gibi, bu ile yapılır
jenerikObject.getClass().getName()
Ayrıca, oluşturulan parametre nesnesi ile ilişkili mesaj
yapıcı tarafından alınabilir
jenerikObject.getMessage()
Ayrıca, kullanıcı tanımlı istisnalar olması durumunda, fırlatılan nesne
işleyicide yararlı olabilecek herhangi bir sayıda veri alanını içerir.
Atar Java yantümce pro içinde görünüm ve yerleştirme (vardır
gram) C++' ın atma belirtimine benzer . Ancak
fırlatmanın anlamı , C++ fırlatma yan tümcesinden biraz farklıdır .
Bir Java'nın throws yan tümcesinde bir istisna sınıfı adının görünümü
yöntem, o istisna sınıfının veya onun herhangi bir alt istisnasının olduğunu belirtir.
sınıflar atılabilir ancak yöntem tarafından işlenmez. Örneğin, ne zaman bir
yöntem , IOException atabileceğini belirtir, bu, bir atabileceği anlamına gelir.
IOException nesnesi veya alt sınıflarından herhangi birinin nesnesi, örneğin
EOFException ve oluşturduğu istisnayı işlemez.
Error ve RuntimeException sınıfının istisnaları ve bunların torunları
denetlenmeyen istisnalar olarak adlandırılır . Diğer tüm istisnalar işaretli olarak adlandırılır
istisnalar . Denetlenmeyen istisnalar hiçbir zaman derleyiciyi ilgilendirmez. Nasıl-
derleyici, bir yöntemin atabileceği tüm kontrol edilen istisnaların
ya onun atma yan tümcesinde listelenir ya da yöntemde işlenir. Dikkat edin, kontrol edin-
Bunu derleme zamanında yapmak, çalışma zamanında yapıldığı C++'dan farklıdır. bu
Error ve RuntimeException sınıflarının istisnalarının ve bunların
torunları işaretlenmemişse, herhangi bir yöntemin onları atabileceğidir. Bir program
denetlenmeyen istisnaları yakalayabilir, ancak gerekli değildir.
C++'da olduğu gibi, bir yöntem kendi içinde daha fazla istisna bildiremez.
daha az bildirebilse de, geçersiz kıldığı yöntemden daha fazla yan tümce atar . Böyle
bir yöntemin hiçbir throws yan tümcesi yoksa , onu geçersiz kılan herhangi bir yöntem de olamaz. A
method, throws yan tümcesinde listelenen herhangi bir istisnayı , bunlardan herhangi biriyle birlikte atabilir .
onun soyundan gelen sınıflar.
Doğrudan belirli bir istisna oluşturmayan, ancak çağıran bir yöntem
bu istisnayı atabilecek başka bir yöntem istisnayı listelemelidir
onun fırlatma maddesinde. buildDist yönteminin nedeni budur (
sonraki alt bölümdeki örnek), readLine yöntemini kullanan,
belirtmek IOException içinde atar onun başlığının maddesini.

Sayfa 672
Java Handling 14.4 İstisna 651
Bir throws yan tümcesi içermeyen bir yöntem, herhangi bir
kontrol edilen istisna C++'da, throw yan tümcesi olmayan bir işlevin
herhangi bir istisna atmak .
Kontrol edilen belirli bir istisnayı listeleyen bir yöntemi çağıran bir yöntem.
throws yan tümcesinin bu istisnayla başa çıkmak için üç alternatifi vardır: Birincisi,
istisnayı yakalayın ve halledin. İkincisi, istisnayı yakalayabilir ve fırlatabilir
kendi throws yan tümcesinde listelenen bir istisna . Üçüncüsü, beyan edebilir
istisna, kendi throws yan tümcesindeki ve onu işlemeyen, etkili bir şekilde
istisnayı , varsa, çevreleyen bir try yan tümcesine veya
ekleyen try yan tümcesi yoksa yöntemin arayanı .
Varsayılan istisna işleyici yoktur ve devre dışı bırakmak mümkün değildir
istisnalar. Java'da devam, tam olarak C++'daki gibidir.
14.4.5 Bir Örnek
Aşağıda C++ programının özelliklerine sahip Java programı verilmiştir.
Bölüm 14.3.5:
// Not Dağılımı
// Giriş: Temsil eden tamsayı değerlerinin bir listesi
//
notlar, ardından negatif bir sayı
// Çıktı: Yüzde olarak notların dağılımı
//
0-9, 10-19 kategorilerinin her biri, . . .,
//
90-100.
java.io'yu içe aktar *;
// Verinin sonunu ele alacak istisna tanımı
class NegativeInputException , İstisna'yı genişletir {
genel NegativeInputException() {
System.out.println("Giriş verilerinin sonuna ulaşıldı");
} //** yapıcının sonu
} //** NegativeInputException sınıfının sonu
sınıf GradeDist {
int yeniSınıf,
dizin,
sınır_1,
limit_2;
int [] frekans = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
void buildDist(), IOException {'yi atar
DataInputStream in = new DataInputStream(System.in);
denemek {
while (doğru) {
System.out.println("Lütfen bir not giriniz");
newGrade = Tamsayı.parseInt(in.readLine());
if (yeniSınıf < 0)

Sayfa 673
652
Bölüm 14 İstisna İşleme ve Olay İşleme
yeni NegativeInputException() atın ;
dizin = yeniSınıf / 10;
denemek {
sıklık[indeks]++;
} //** iç try yan tümcesinin sonu
yakalamak (ArrayIndexOutOfBoundsException e) {
if (yeniSınıf == 100)
sıklık [9]++;
Başka
System.out.println("Hata - yeni not: " +
newGrade + " aralık dışında");
} //** yakalama sonu (ArrayIndex. . .
} //** while sonu (true) . . .
} //** dış try yan tümcesinin sonu
yakalamak (NegativeInputException e) {
System.out.println ("\nSınırları Sınırlar\n");
for (indeks = 0; dizin < 10; dizin++) {
limit_1 = 10 * dizin;
limit_2 = limit_1 + 9;
if (indeks == 9)
limit_2 = 100;
System.out.println("" + limit_1 + " - " +
limit_2 + " " + frekans [indeks]);
} //** for sonu (indeks = 0; . . .
} //** yakalama sonu (NegativeInputException . . .
} //** buildDist yönteminin sonu
Negatif girdi için istisna, NegativeInputException tanımlanmıştır
programda. Oluşturucusu, sınıfın bir nesnesi olduğunda bir mesaj görüntüler.
yaratıldı. İşleyicisi, yöntemin çıktısını üretir. ArrayIndexOutOf-
BoundsException tarafından oluşturulan önceden tanımlanmış denetlenmemiş bir istisnadır.
Java çalışma zamanı sistemi. Bu durumların her ikisinde de işleyici şunları içermez:
parametresinde bir nesne adı. Her iki durumda da bir isim herhangi bir şeye hizmet etmez
amaç. Tüm işleyiciler nesneleri parametre olarak alsalar da, çoğu zaman değildirler.
kullanışlı.
14.4.6 Son Madde
Ne olursa olsun bir işlemin yürütülmesi gereken bazı durumlar vardır.
bir try yan tümcesinin bir istisna atıp atmadığı ve atılmış olup olmadığına bakılmaksızın
istisna bir yöntemde yakalanır. Böyle bir duruma bir örnek, bir dosyadır.
kapatılmalıdır. Bir diğeri, yöntemin kullanması gereken bazı dış kaynaklara sahip olup olmadığıdır.
yöntemin yürütülmesinin nasıl sona erdiğine bakılmaksızın yöntemde serbest bırakılmalıdır.
nates. Nihayet fıkra ihtiyaçları bu tür için tasarlanmıştır. bir nihayet
fıkra sadece tam sonra işleyicileri listenin sonunda yer alıyor denemede kon-
yapı. Genel olarak, try yapısı ve nihayet yan tümcesi şu şekilde görünür:

Sayfa 674
14.4 Java 653'te İstisna İşleme
denemek {
. . .
}
yakalamak (. . .) {
. . .
}
. . . //** Daha fazla işleyici
nihayet {
. . .
}
Bu yapının semantiği şu şekildedir: try yan tümcesi hayır atarsa
istisnalar, nihayet yan tümcesi yürütme devam etmeden önce yürütülür.
deneyin yapı. Eğer deneyin hükmü bir istisna atar ve a ile yakalanır
işleyiciyi takiben, işleyici tamamlandıktan sonra nihayet yan tümcesi yürütülür.
onun yürütülmesi. Eğer deneyin hükmü bir istisna atar ancak a tarafından yakalanmış değil
işleyici, try yapısını takip ederse , nihayet yan tümcesi daha önce yürütülür.
istisna yayılır.
İstisna işleyicileri olmayan bir try yapısını bir nihayet takip edebilir.
madde. Bu, elbette, yalnızca bileşik ifadenin bir
throw , break , Continue veya return ifadesi. Bu durumlarda amacı
istisna işleme ile kullanıldığında aynıdır. Örneğin, düşünün
devamındaki:
denemek {
for (indeks = 0; dizin < 100; dizin++) {
. . .
eğer (. . . ) {
dönüş ;
} //** if'nin sonu
. . .
} //** için sonu
} //** try yan tümcesinin sonu
nihayet {
. . .
} //** try yapısının sonu
Buradaki nihayet maddesi, dönüşün olup olmadığına bakılmaksızın yürütülecektir.
döngüyü sonlandırır veya normal şekilde biter.
14.4.7 İddialar
Plankalkül'ün Bölüm 2'deki tartışmasında, içerdiğinden bahsetmiştik.
iddialar. Java'ya 1.4 sürümünde iddialar eklendi. Bunları kullanmak için gerekli-
programı enableassertions ile çalıştırarak bunları etkinleştirmek için makale
(veya ea ) bayrağı, olduğu gibi

Sayfa 675
654
Bölüm 14 İstisna İşleme ve Olay İşleme
java -enableassertions MyProgram
Assert ifadesinin iki olası biçimi vardır :
şart koş ;
iddia koşulu : ifade ;
İlk durumda, yürütme assert değerine ulaştığında koşul test edilir .
Koşul true olarak değerlendirilirse hiçbir şey olmaz. false olarak değerlendirilirse,
AssertionError istisnası atıldı. İkinci durumda, eylem,
aynı, ancak ifadenin değerinin AssertionError'a iletilmesi dışında
yapıcı bir dize olarak ve hata ayıklama çıktısı olur.
Assert deyimi defansif programlama için kullanılır. Bir program
programın doğruluğunu garanti eden birçok assert ifadesiyle yazılabilir.
hesaplama doğru sonuçlar üretmek için yolda. Birçok programcı koydu
hata ayıklamaya yardımcı olmak için bir program yazarken bu tür kontroller
kullandıkları dil iddiaları desteklemiyor. program ne zaman
yeterince test edilirse, bu kontroller kaldırılır. İddianın avantajı
Aynı amaca sahip ifadeler, bunların devre dışı bırakılabilmesidir.
onları programdan kaldırmak. Bu, onları kaldırma çabasından tasarruf sağlar ve
ayrıca sonraki program bakımı sırasında kullanımlarına izin verir.
14.4.8 Değerlendirme
İstisna işleme için Java mekanizmaları, C++ üzerinde bir gelişmedir.
dayandıkları sürüm.
İlk olarak, bir C++ programı, programda veya program tarafından tanımlanan herhangi bir türü atabilir.
sistem. Java'da, yalnızca Throwable veya bazı sınıf örnekleri olan nesneler
ondan inen atılabilir. Bu, olabilecek nesneleri ayırır.
bir programda bulunan diğer tüm nesnelerden (ve nesne olmayanlardan) atılır.
Bir int değerine neden olan bir istisnaya hangi önem atfedilebilir?
atılmak mı?
İkinci olarak, bir throw yan tümcesi içermeyen bir C++ program birimi ,
okuyucuya hiçbir şey söylemeyen herhangi bir istisna atın. yapan bir Java yöntemi
fırlatma maddesi içermez, yaptığı herhangi bir kontrol edilmiş istisnayı atamaz
işlemek değil. Bu nedenle, bir Java yönteminin okuyucusu, başlığından neyin ne olduğunu bilir.
atabileceği ancak işlemediği istisnalar. Bir C++ derleyicisi fırlatmayı yok sayar
yan tümceler, ancak bir Java derleyicisi, bir yöntemin atabileceği tüm istisnaların
Fırlatma yan tümcesinde listelenir .
Üçüncüsü, nihayet ibaresinin eklenmesi bazı durumlarda büyük kolaylık sağlar.
durumlar. Nasıl yapılırsa yapılsın temizleme eylemlerinin gerçekleşmesine izin verir.
bileşik ifade sonlandırıldı.
Son olarak, Java çalışma zamanı sistemi örtük olarak önceden tanımlanmış çeşitli
aralık dışı dizi indeksleri ve boş referansın kaldırılması gibi istisnalar
herhangi bir kullanıcı programı tarafından işlenebilir. Bir C++ programı işleyebilir
yalnızca açıkça attığı (veya kitaplık tarafından atılan) istisnalar
kullandığı sınıflar).

Sayfa 676
14.5 Olay Yönetimine Giriş 655
Ada'nın istisna işlemesine göre, Java'nın tesisleri kabaca
karşılaştırılabilir. Bir Java yönteminde throws yan tümcesinin varlığı,
okunabilirlik, Ada'nın karşılık gelen bir özelliği yoktur. Java kesinlikle daha yakın
Ada'ya, bir alanda C++'a olduğundan daha fazla - programların başa çıkmasına izin verme
sistem tarafından algılanan istisnalar.
C#, bunlara çok benzeyen istisna işleme yapıları içerir
C#'ın bir throws yan tümcesi olmaması dışında .
14.5 Olay Yönetimine Giriş
Olay işleme, istisna işlemeye benzer. Her iki durumda da, işleyiciler
bir istisna veya bir şeyin ortaya çıkmasıyla dolaylı olarak çağrılır.
bir etkinlik. İstisnalar ya kullanıcı koduyla ya da
dolaylı olarak donanım veya yazılım yorumlayıcısı tarafından, olaylar harici
grafik kullanıcı arabirimi (GUI) aracılığıyla kullanıcı etkileşimleri gibi eylemler. İçinde
bu bölümde, önemli ölçüde daha az olan olay işlemenin temelleri
istisna işlemeden daha karmaşık, tanıtıldı.
Geleneksel (olay güdümlü olmayan) programlamada, program kodunun kendisi
bu kodun yürütüldüğü sırayı belirtir, ancak sıra genellikle
programın giriş verilerinden etkilenir. Olay güdümlü programlamada,
program tamamen öngörülemeyen zamanlarda yürütülür, genellikle tetiklenir
yürütme programı ile kullanıcı etkileşimleri tarafından.
Bu bölümde tartışılan belirli olay işleme türü, aşağıdakilerle ilgilidir:
GUI'ler. Bu nedenle, olayların çoğu kullanıcı etkileşimlerinden kaynaklanır.
genellikle widget olarak adlandırılan grafik nesneler veya bileşenler . En yaygın geniş-
alır düğmelerdir. GUI iletişimi ile kullanıcı etkileşimlerine tepkileri uygulama
Bileşenler, olay işlemenin en yaygın biçimidir.
Bir olay bir şey özgü böyle bir şekilde oluştuğunu bildiren bir bildirim
fare ile grafik bir düğmeye tıklayın. Kesin olarak söylemek gerekirse, bir olay bir nesnedir.
en azından bir kullanıcı eylemine yanıt olarak çalışma zamanı sistemi tarafından dolaylı olarak oluşturulur.
olay işlemenin burada tartışıldığı bağlamda.
Bir olay giderici yanıt olarak yürütülür kod bölümdür
bir olayın görünüşü. Olay işleyicileri, bir programın yanıt vermesini sağlar
kullanıcı eylemleri.
Olay güdümlü programlama GUI'lerden çok önce kullanılsa da
ortaya çıktı, ancak yaygın olarak kullanılan bir programlama metodolojisi haline geldi.
Bu arayüzlerin popülaritesine yanıt. Örnek olarak,
Web tarayıcılarının kullanıcılarına sunulan GUI'ler. Sunulan birçok Web belgesi
tarayıcı kullanıcıları artık dinamik. Böyle bir belge bir sipariş formu sunabilir
düğmelere tıklayarak ürünü seçen kullanıcıya. Gerekli olan
bu düğme tıklamalarıyla ilişkili dahili hesaplamalar,
tıklama olaylarına tepki veren olay işleyicileri.
Olay işleyicilerin diğer bir yaygın kullanımı, basit hataları kontrol etmek ve
Bir formun öğelerindeki eksiklikler, değiştirildiğinde veya değiştirildiğinde
form işlenmek üzere Web sunucusuna gönderilir. Olay işlemeyi kullanma

Sayfa 677
656
Bölüm 14 İstisna İşleme ve Olay İşleme
Form verilerinin geçerliliğini kontrol etmek için tarayıcıda, gönderme süresinden tasarruf sağlar
bu veriler sunucuya gönderilir, burada doğrulukları daha sonra bir yetkili tarafından kontrol edilmelidir.
sunucuda yerleşik program veya komut dosyası işlenmeden önce. Bu tür
olay güdümlü programlama genellikle istemci tarafı bir betik dili kullanılarak yapılır,
JavaScript gibi.
14.6 Java ile Olay İşleme
Web uygulamalarına ek olarak, Web dışı Java uygulamaları GUI'ler sunabilir.
kullanıcılara. Java uygulamalarındaki GUI'ler bu bölümde tartışılmaktadır.
Java'nın ilk sürümü, biraz ilkel bir destek biçimi sağladı.
GUI bileşenleri için bağlantı noktası. Geç yayınlanan dilin 1.2 sürümünde
1998, yeni bir bileşen koleksiyonu eklendi. Bunlar toplu haldeydi
salıncak denir.
14.6.1 Java Swing GUI Bileşenleri
javax.swing içinde tanımlanan sınıfların ve arabirimlerin Swing koleksiyonu ,
GUI bileşenleri veya widget'ları içerir. Çünkü buradaki ilgimiz olay han-
GUI bileşenleri değil, dling, yalnızca iki tür widget'ı tartışıyoruz: metin kutuları
ve radyo düğmeleri.
Metin kutusu, JTextField sınıfının bir nesnesidir . En basit JTextField
yapıcı, kutunun karakter cinsinden uzunluğu olan tek bir parametre alır. İçin
örnek,
JTextField adı = yeni JTextField(32);
JTextField yapıcısı Ayrıca isteğe bağlı olarak değişmez bir dize alabilir
ilk parametre. Bu dize parametresi, mevcut olduğunda, ilk olarak görüntülenir.
metin kutusunun içeriği.
Radyo düğmeleri, bir düğme grubuna yerleştirilen özel düğmelerdir.
kap. Bir düğme grubu, yapıcısı olan ButtonGroup sınıfının bir nesnesidir.
parametre almaz. Bir radyo düğmesi grubunda yalnızca bir düğmeye basılabilir
zamanında. Gruptaki herhangi bir düğmeye basıldığında, daha önce basılan
düğmesine dolaylı olarak basılmaz. JRadioButton yaratıcı- için kullanılan yapıcı,
radyo düğmelerini kullanırken, iki parametre alır: bir etiket ve
radyo düğmesi ( sırasıyla basılan ve basılmayan için true veya false ). Eğer
gruptaki bir radyo düğmesi başlangıçta basılı olarak ayarlanır, diğerleri grupta
varsayılan olarak basılı değildir. Radyo düğmeleri oluşturulduktan sonra,
düğme grubu , grup nesnesinin ekleme yöntemiyle. Yi hesaba kat
aşağıdaki örnek:
ButtonGroup ödemesi = new ButtonGroup();
JRadioButton box1 = new JRadioButton("Visa", true);

Sayfa 678
14.6 Java 657 ile Olay İşleme
JRadioButton box2 = new JRadioButton("Ana Şarj");
JRadioButton box3 = new JRadioButton("Keşfet");
ödeme.add(kutu1);
ödeme.add(kutu2);
ödeme.add(kutu3);
Bir JFrame nesne ayrı bir pencere olarak görüntülenen bir çerçeve olup. bu
JFrame sınıfı, çerçeveler için gerekli olan veri ve yöntemleri tanımlar. Böyle,
çerçeve kullanan bir sınıf, JFrame öğesinin bir alt sınıfı olabilir . Bir JFrame'in birkaç
bölmeler olarak adlandırılan katmanlar . Biz bu katmanlardan sadece biriyle ilgileniyoruz.
çadır bölmesi. Bir GUI'nin bileşenleri bir JPanel nesnesine (bir panel) yerleştirilir,
bileşenlerin düzenini düzenlemek ve tanımlamak için kullanılır. bir çerçeve
oluşturulur ve bileşenleri içeren panel o çerçeveye eklenir.
içerik bölmesi.
GUI bileşenleri gibi önceden tanımlanmış grafik nesneleri doğrudan
bir panelde. Aşağıdaki, aşağıdaki tartışmalarda kullanılan panel nesnesini oluşturur:
bileşenlerin siyonu:
JPanel myPanel = yeni JPanel();
Bileşenler yapıcılar ile oluşturulduktan sonra yerleştirilirler.
panelde olduğu gibi add yöntemiyle
myPanel.add(düğme1);
14.6.2 Java Olay Modeli
Bir kullanıcı bir GUI bileşeniyle etkileşim kurduğunda, örneğin bir butona tıklayarak
ton, bileşen bir olay nesnesi oluşturur ve aracılığıyla bir olay işleyicisini çağırır.
olay nesnesini geçen olay dinleyicisi adlı bir nesne. olay işleyici
ilgili eylemleri sağlar. GUI bileşenleri olay oluşturuculardır; onlar
olaylar üretir. Java'da olaylar olay işleyicilerine olay aracılığıyla bağlanır
dinleyiciler . Olay dinleyicileri, olay aracılığıyla olay oluşturuculara bağlanır
dinleyici kaydı Dinleyici kaydı, sınıfın bir yöntemi ile yapılır
bu bölümün ilerleyen kısımlarında açıklandığı gibi dinleyici arabirimini uygulayan. Bir tek
Belirli bir olay için kayıtlı olay dinleyicileri, bu olay gerçekleştiğinde bilgilendirilir.
olay meydana gelir.
Mesajı alan dinleyici yöntemi bir olay han-
dler. Olay işleme yöntemlerini standart bir protokole uygun hale getirmek için, bir
arayüz kullanılır. Bir arabirim, standart yöntem protokollerini belirler, ancak
bu yöntemlerin uygulamalarını sağlamaz.
Bir olay işleyicisi uygulaması gereken bir sınıf, bir
o işleyici için dinleyici için arayüz. Birkaç olay sınıfı var
ve dinleyici arayüzleri. Olayların bir sınıfı, ilişkisel olan ItemEvent'tir.
bir onay kutusunun veya radyo düğmesinin tıklanması veya bir
liste öğesi. ItemListener arayüzü bir yöntemin protokolü içerir,

Sayfa 679
658
Bölüm 14 İstisna İşleme ve Olay İşleme
ItemEvent olaylarının işleyicisi olan itemStateChanged . Yani, pro-
bir radyo düğmesi tıklamasıyla tetiklenen bir eylemi görüntüleyin, arayüz Öğesi-
Yöntemin bir tanımını gerektiren dinleyici uygulanmalıdır,
itemStateChanged .
Daha önce belirtildiği gibi, bir bileşenin bir olay dinleyicisine bağlanması
dinleyici arabirimini uygulayan sınıfın bir yöntemiyle yapılır.
Örneğin, ItemEvent oluşturulan olay nesnelerinin sınıf adı olduğundan
radyo düğmeleri üzerindeki kullanıcı eylemleriyle, addItemListener yöntemi şu şekilde kullanılır:
radyo düğmeleri için bir dinleyici kaydedin. Oluşturulan düğme olayları için dinleyici
panelde veya JPanel'in bir alt sınıfında bir panel uygulanabilir . İçin böylece
uygulayan myPanel adlı bir panelde button1 adlı bir radyo düğmesi
Düğmeler için ItemEvent olay işleyicisi, dinleyiciyi
aşağıdaki ifade:
button1.addItemListener( bu );
Her olay işleyici yöntemi, aşağıdakileri sağlayan bir olay parametresi alır:
etkinlik hakkında bilgi. Olay sınıflarının bu bilgilere erişme yöntemleri vardır.
çiftleşme. Örneğin, bir radyo düğmesi aracılığıyla çağrıldığında, isSelected
düğmenin açık veya kapalı olmasına bağlı olarak yöntem doğru veya yanlış döndürür
(basılı veya basılı değil), sırasıyla.
Olayla ilgili tüm sınıflar java.awt.event paketindedir, yani
olayları kullanan herhangi bir sınıfa aktarılır.
Aşağıdaki örnek bir uygulama, bir RadioB kullanımını göstermektedir,
olaylar ve olay işleme. Bu uygulama radyo düğmeleri oluşturur.
bir metin alanının içeriğinin yazı tipi stilini kontrol edin. için bir Font nesnesi oluşturur .
dört yazı tipi stilinden her biri. Bunların her birinin, kullanıcının şunları yapmasını sağlamak için bir radyo düğmesi vardır.
yazı tipi stilini seçin.
Bu örneğin amacı, GUI bileşimi tarafından oluşturulan olayların nasıl olduğunu göstermektir.
nents, programın çıktı görüntüsünü dinamik olarak değiştirmek için kullanılabilir.
Olay işleme konusundaki dar odak noktamız nedeniyle, bu programın bazı bölümleri
burada anlatılmamış.
/* RadioB.java
Etkileşimli olay işlemeyi gösteren bir örnek
bir metin alanının yazı tipi stilini kontrol eden radyo düğmeleri
*/
paket radyob;
java.awt.* dosyasını içe aktarın ;
java.awt.event.* dosyasını içe aktarın ;
javax.swing'i içe aktarın .*;
public class RadioB , JPanel uygulamalarını genişletiyor
Öğe Dinleyici {
özel JTextField metni;

Sayfa 680
14.6 Java 659 ile Olay İşleme
özel Yazı Tipi düzFont, boldFont, italicFont,
kalınItalikFont;
özel JRadioButton düz, kalın, italik, kalınİtalik;
özel ButtonGroup radyoButtons;
// Yapıcı yöntemi, ekranın başlangıçta olduğu yerdir
// inşa edilmiş
genel RadyoB() {
// Test metin dizesini oluşturun ve yazı tipini ayarlayın
metin = yeni JTextField(
"Hangi yazı tipi stilinde görünmeliyim?", 25);
text.setFont(plainFont);
// Yazı tipleri için radyo düğmeleri oluşturun ve bunları
// yeni bir düğme grubu
düz = new JRadioButton("Düz", true );
kalın = new JRadioButton("Kalın");
italik = new JRadioButton("İtalik");
boldItalic = new JRadioButton("Kalın İtalik");
radioButtons = new ButtonGroup();
radioButtons.add(düz);
radioButtons.add(kalın);
radioButtons.add(italik);
radioButtons.add(boldItalic);
// Bir panel oluşturun ve metni ve radyoyu yerleştirin
// içindeki butonlar; ardından paneli çerçeveye ekleyin
JPanel radioPanel = yeni JPanel();
radioPanel.add(metin);
radioPanel.add(düz);
radioPanel.add(kalın);
radioPanel.add(italik);
radioPanel.add(boldItalik);
add(radioPanel, BorderLayout.LINE_START);
// Olay işleyicilerini kaydedin
düz.addItemListener( bu );
kalın.addItemListener( bu );
italic.addItemListener( bu );
boldItalic.addItemListener( bu );
// Fontları oluştur
düzFont = new Font("Serif", Font.PLAIN, 16);
boldFont = new Font("Serif", Font.BOLD, 16);

Sayfa 681
660
Bölüm 14 İstisna İşleme ve Olay İşleme
italicFont = new Font("Serif", Font.ITALIC, 16);
boldItalicFont = new Font("Serif", Font.BOLD +
Font.ITALIC, 16);
} // RadioB için kurucunun sonu
// Olay işleyicisi
public void itemStateChanged (ItemEvent e) {
// Hangi düğmenin açık olduğunu belirleyin ve yazı tipini ayarlayın
// buna göre
if (plain.isSelected())
text.setFont(plainFont);
else if (bold.isSelected())
text.setFont(boldFont);
else if (italic.isSelected())
text.setFont(italicFont);
else if (boldItalic.isSelected())
text.setFont(boldItalicFont);
} // itemStateChanged'ın sonu
// ana yöntem
public static void main(String[] args) {
// Pencere çerçevesini oluştur
JFra me myFrame = yeni JFrame(" Radyo düğmesi
örnek");
// İçerik bölmesini oluşturun ve çerçeveye ayarlayın
JComponent myContentPane = new RadioB();
myContentPane.setOpaque( true );
myFrame.setContentPane(myContentPane);
// Pencereyi göster.
myFrame.pack();
myFrame.setVisible( doğru );
}
} // RadioB'nin Sonu
RadioB.java uygulaması Şekil 14.2 gösterilen ekran üretir.
Şekil 14.2
çıktısı
RadioB.java

Sayfa 682
14.7 C# 661'de Olay İşleme
14.7 C#'da Olay İşleme
C#'da (ve diğer .NET dillerinde) olay işleme buna benzer
Java'nın. .NET, uygulamalarda GUI oluşturmaya yönelik iki yaklaşım sağlar:
orijinal Windows Formları ve daha yeni Windows Presentation Foundation-
tion. İkincisi, ikisinin daha karmaşık ve karmaşık olanıdır. Çünkü bizim
ilgi sadece olay işlemede, daha basit Windows Formlarını kullanacağız.
konumuzu tartışın.
Windows Forms kullanılarak, bir GUI oluşturan bir C# uygulaması tarafından oluşturulur.
System.Windows'ta tanımlanan Form ön tanımlı sınıfının alt sınıflandırması
.Forms ad alanı. Bu sınıf, örtük olarak bizim içeriğimizi içeren bir pencere sağlar.
bileşenler. Açıkça çerçeveler veya paneller oluşturmaya gerek yoktur.
Metin bir Label nesnesine yerleştirilebilir ve radyo düğmeleri,
RadioButton sınıfı. Bir Label nesnesinin boyutu açıkça belirtilmemiş
yapıcıda; bunun yerine, AutoSize verileri ayarlanarak belirtilebilir.
Etiket nesnesinin üyesi true , bu da boyutu neye göre ayarlar
içine yerleştirilir.
Bileşenler, atama yoluyla pencerede belirli bir konuma yerleştirilebilir.
bileşenin Location özelliğine yeni bir Point nesnesi ekleme . bu
Point sınıfı, System.Drawing ad alanında tanımlanır . Nokta kon-
structor, nesnenin piksel cinsinden koordinatları olan iki parametre alır.
Örneğin, Nokta(100, 200) , soldan 100 piksel olan bir konumdur.
pencerenin kenarı ve üstten 200 piksel. Bir bileşenin etiketi
bileşenin Text özelliğine bir dize değişmez değeri atayarak ayarlayın . Sonrasında
Bir bileşen oluşturulduğunda, Ekle'ye gönderilerek form penceresine eklenir.
formun Denetimler alt sınıfının yöntemi . Bu nedenle aşağıdaki kod
etiket ile radyo düğmesini oluşturur Ovası'nda de (100, 300) pozisyon
çıkış penceresi:
özel RadioButton düz = yeni RadioButton();
düz.Konum = yeni Nokta(100, 300);
düz.Text = "Düz";
Kontroller.Add(düz);
Tüm C# olay işleyicileri aynı protokole sahiptir: dönüş türü geçersizdir
ve iki parametre object ve EventArgs türündedir . hiçbiri
parametrelerin basit bir durum için kullanılması gerekir. Bir olay işleyici yöntemi
herhangi bir isim olabilir. Tıklanıp tıklanmadığını belirlemek için bir radyo düğmesi test edilir
Düğmenin Boolean Checked özelliği ile. Aşağıdakileri göz önünde bulundur
bir olay işleyicisinin iskelet örneği:
private void rb_CheckedChanged ( nesne o, EventArgs e){
if (düz.İşaretli) . . .
. . .
}

Sayfa 683
662
Bölüm 14 İstisna İşleme ve Olay İşleme
Bir olayı kaydetmek için yeni bir EventHandler nesnesi oluşturulmalıdır. con-
Bu sınıf için yapılandırıcıya, işleyici yönteminin adı gönderilir. Yeni nesne
bileşen nesnesindeki olay için önceden tanımlanmış temsilciye eklendi (kullanarak
+= atama operatörü). Örneğin, bir radyo düğmesi işaretlenmemiş durumundan değiştiğinde
kontrol etmek için CheckedChanged olayı başlatılır ve işleyiciler
olayın adıyla başvurulan ilişkili temsilci çağrılır. Eğer
olay işleyicisi rb_CheckedChanged olarak adlandırılır , aşağıdaki ifade
işleyiciyi CheckedChanged olayı için radyo düğmesi düzlüğüne kaydedin :
sade. Kontrol EdildiDeğiştirildi +=
new EventHandler(rb_CheckedChanged);
Aşağıda, C# ile yeniden yazılmış Bölüm 14.6'daki RadioB örneği verilmiştir. Bir kere
yine, odak noktamız olay işlemeye yönelik olduğundan, bunların tümünü açıklamıyoruz.
programın detayları.
// RadioB.cs
// Olay işlemeyi gösteren bir örnek
// yazı tipini kontrol eden etkileşimli radyo düğmeleri
// bir metin dizisinin stili
ad alanı RadioB {
Sistemi kullanarak ;
System.Drawing'i kullanarak ;
System.Windows.Forms'u kullanarak ;
public class RadioB : Form {
özel Etiket metni = yeni Etiket();
özel RadioButton düz = yeni RadioButton();
özel RadioButton kalın = yeni RadioButton();
özel RadioButton italik = yeni RadioButton();
private RadioButton boldItalic = new RadioButton();
// RadioB için Oluşturucu
genel RadyoB() {
// Metnin ve radyonun niteliklerini başlat
// düğmeler
text.AutoSize = true ;
text.Text = "Hangi yazı tipi stilinde görünmeliyim?";
düz.Konum = yeni Nokta(220,0);
düz.Text = "Düz";
düz.Kontrol edildi = doğru ;
kalın.Konum = yeni Nokta(350, 0);

Sayfa 684
14.7 Olay C Taşıma # 663
kalın.Text = "Kalın";
italik.Konum = yeni Nokta(480, 0);
italic.Text = "İtalik";
boldItalic.Location = new Point(610, 0);
boldItalic.Text = "Kalın/İtalik";
// Metni ve radyo düğmelerini forma ekleyin
Kontroller.Add(metin);
Kontroller.Add(düz);
Kontroller.Add(kalın);
Controls.Add(italik);
Controls.Add(boldItalic);
// Radyo düğmeleri için olay işleyicisini kaydedin
düz .CheckedChanged +=
new EventHandler(rb_CheckedChanged);
gözü pek. Kontrol EdildiDeğiştirildi +=
new EventHandler(rb_CheckedChanged);
itali c.Kontrol EdildiDeğiştirildi +=
new EventHandler(rb_CheckedChanged);
boldI talic.CheckedChanged +=
new EventHandler(rb_CheckedChanged);
}
// Ana yöntem, yürütmenin başladığı yerdir
statik boşluk Main() {
Application.EnableVisualStyles();
Uygulama.SetCompatibleTextRenderingDefault
( yanlış );
Application.Run( yeni RadioB());
}
// Olay işleyicisi
private void rb_CheckedChanged ( nesne o,
EventArgs e) {
// Hangi düğmenin açık olduğunu belirleyin ve yazı tipini ayarlayın
// buna göre
if (düz.İşaretli)
metin.Font =
new Font( text.Font.Name, text.Font.Size,
FontStyle.Regular);
if (kalın.İşaretli)
metin.Font =

Sayfa 685
664
Bölüm 14 İstisna İşleme ve Olay İşleme
new Font( text.Font.Name, text.Font.Size,
FontStyle.Bold);
if (italik.İşaretli)
metin.Font =
new Font( text.Font.Name, text.Font.Size,
FontStyle.Italic);
if (kalınİtalik.İşaretli)
metin.Font =
new Font( text.Font.Name, text.Font.Size,
FontStyle.Italic ^ FontStyle.Bold);
} // radioButton_CheckedChanged'ın sonu
} // RadioB'nin Sonu
}
Bu programın çıktısı tam olarak Şekil 14.2'de gösterilene benzer.
ÖZET
En yaygın olarak kullanılan programlama dilleri artık istisna işlemeyi içermektedir.
Ada, kapsamlı istisna işleme tesisleri ve küçük ama
yerleşik istisnaların kapsamlı koleksiyonu. İşleyiciler,
program varlıkları, ancak istisnalar örtük veya açık bir şekilde yayılabilir
yerel işleyici yoksa diğer program varlıklarına.
C++ önceden tanımlanmış istisnalar içermez (standartta tanımlananlar hariç).
dar kitaplık). C++ istisnaları, ilkel türden nesnelerdir, önceden tanımlanmış bir
sınıf veya kullanıcı tanımlı bir sınıf. İstisnalar, bağlantı yoluyla işleyicilere bağlıdır.
throw ifadesindeki ifadenin tipini resmi ifadenin tipine çevirmek
işleyicinin parametresi. İşleyicilerin tümü aynı ada sahiptir - catch . bu
Bir yöntemin C++ throw yan tümcesi, yöntemin sunduğu istisna türlerini listeler.
atabilirdi.
Java istisnaları, atalarının izini bir sınıfa kadar takip etmesi gereken nesnelerdir.
iner Atılabil sınıfa. İstisnaların iki kategorisi vardır—
kontrol edildi ve kontrol edilmedi. Kontrol edilen istisnalar, kullanıcı pro-
gram ve derleyici. Denetlenmeyen istisnalar herhangi bir yerde ortaya çıkabilir ve
genellikle kullanıcı programları tarafından göz ardı edilir.
Java atar bir yöntem listelerinin maddesini kontrol istisnalar öyle
fırlatabilir ve tutamaz. Yöntemleri olan istisnaları içermelidir.
çağrılar artabilir ve arayana geri dönebilir.
Java nihayet yan tümcesi, bunu garanti etmek için bir mekanizma sağlar.
bir deneme bileşiğinin nasıl yürütüldüğüne bakılmaksızın bazı kodlar yürütülür.
sona erer.
Java artık savunmayı kolaylaştıran bir assert ifadesi içerir.
programlama.

Sayfa 686
Soruları gözden geçir 665
Olay, özel gereksinimler gerektiren bir şeyin meydana geldiğine dair bir bildirimdir.
sosyal işlem. Olaylar genellikle bir programla kullanıcı etkileşimleri tarafından oluşturulur.
bir grafik kullanıcı arayüzü aracılığıyla. Java olay işleyicileri olay aracılığıyla çağrılır
dinleyiciler. Bir olaya dikkat edilmesi için olay dinleyicisinin kayıtlı olması gerekir.
olay meydana geldiğinde verilir. En sık kullanılan olay dinleyicilerinden ikisi
arabirimler actionPerformed ve itemStateChanged'dir .
Windows Forms, GUI bileşenleri oluşturmaya yönelik orijinal yaklaşımdır
ve .NET dillerinde olayları işleme. AC# uygulaması bunun içinde bir GUI oluşturur
Form sınıfını alt sınıflara ayırarak yaklaşım . Tüm .NET olay işleyicileri aynı
protokol. Olay işleyicileri, bir EventHandler nesnesi oluşturularak kaydedilir
ve onu GUI nesnesiyle ilişkili önceden tanımlanmış temsilciye atamak
olayı yükseltebilir.
KAYNAKÇA NOTLAR
Bağlantılı olmayan özel durum işleme konusundaki en önemli makalelerden biri
Belirli bir programlama dili ile Goodenough'un (1975) eseridir.
İstisna işleme için PL/I tasarımıyla ilgili sorunlar,
MacLaren (1977). CLU özel durum işleme tasarımı tarafından açıkça tanımlanmıştır.
Liskov ve Snyder (1979). Ada dilinin özel durum işleme tesisleri
ARM'de (1995) tanımlanmıştır ve Romanovsky ve
Sanden (2001). C++'da özel durum işleme, Stroustrup (1997) tarafından açıklanmıştır.
Java'da özel durum işleme, Campione ve diğerleri tarafından açıklanmıştır. (2001).
İNCELEME SORULARI
Define 1. istisna , istisna işleyicisi , bir özel durum , bir excep- devre dışı bırakma
tion , continuation , finalization ve yerleşik özel durum .
2. Devamını tasarlamak için iki alternatif nedir?
3. Özel durum işleme desteğine sahip olmanın avantajları nelerdir?
bir dilde?
4. İstisna işleme için tasarım sorunları nelerdir?
5. Bir istisnanın bir istisnaya bağlı olması ne anlama gelir?
işleyici?
6. Ada'daki istisnalar için olası çerçeveler nelerdir?
7. Bir alt pro-
gram? Bir blok? Paket gövde mi? Bir görev?
8. Ada'da bir istisna işlendikten sonra yürütme nerede devam ediyor?
9. Ada'da açıkça bir istisna nasıl ortaya çıkarılabilir?
10. Ada'nın Standart paketinde tanımlanan dört istisna nedir ?

Sayfa 687
666
Bölüm 14 İstisna İşleme ve Olay İşleme
11. Ada'da kullanıcı tanımlı bir istisna nasıl tanımlanır?
12. Ada'da bir istisna nasıl bastırılabilir?
13. Ada'nın istisna işlemesiyle ilgili üç sorunu tanımlayın.
14. Tüm C++ istisna işleyicilerinin adı nedir?
15. C++'da istisnalar nasıl açıkça ortaya çıkarılabilir?
16. C++'da istisnalar işleyicilere nasıl bağlanır?
17. Bir istisna işleyicisi, herhangi bir durumu işleyebilmesi için C++ ile nasıl yazılabilir?
istisna?
18. Bir C++ istisna işleyicisi olduğunda yürütme denetimi nereye gider?
yürütmesini tamamladı mı?
19. C++ yerleşik istisnalar içeriyor mu?
20. C++'da bir istisnanın yükseltilmesi neden yükseltme olarak adlandırılmıyor?
21. Tüm Java istisna sınıflarının kök sınıfı nedir?
22. Java kullanıcı tanımlı istisna sınıflarının çoğunun üst sınıfı nedir?
23. Bir istisna işleyicisi, herhangi bir durumu işleyebilmesi için Java'da nasıl yazılabilir?
istisna?
24. C++ atma özelliği ile Java arasındaki farklar nelerdir?
fıkra atar ?
25. Java'da işaretli ve işaretlenmemiş istisnalar arasındaki fark nedir?
26. Bir istisna işleyicisi, herhangi bir durumu işleyebilmesi için Java'da nasıl yazılabilir?
istisna?
27. Bir Java istisnasını devre dışı bırakabilir misiniz?
28. Java nihayet yan tümcesinin amacı nedir ?
29. dil tanımlı iddialar basit üzerinde var ne avantajı ise -
yazma yapılar?
30. İstisna işleme ve olay işleme hangi yollarla ilişkilidir?
31. Olay ve olay işleyiciyi tanımlayın.
32. Olaya dayalı programlama nedir?
33. Java JFrame'in amacı nedir ?
34. Java JPanel'in amacı nedir ?
35. Java GUI uygulamalarında olay dinleyicisi olarak sıklıkla hangi nesne kullanılır?
36. Java'da bir olay işleyicisi için protokolün kaynağı nedir?
37. Java'da bir olay işleyiciyi kaydetmek için hangi yöntem kullanılır?
38. .NET'in Windows Forms'unu kullanarak, bir ad alanı oluşturmak için hangi ad alanının gerekli olduğu
Bir C# uygulaması için GUI?
39. Windows Forms kullanılarak bir formda bir bileşen nasıl konumlandırılır?
40. Bir .NET olay işleyicisinin protokolü nedir?
41. Bir .NET olay işleyicisini kaydetmek için hangi nesne sınıfı oluşturulmalıdır?
42. Olay işleyicilerini kaydetme sürecinde temsilciler nasıl bir rol oynar?

Sayfa 688
Problem Seti 667
PROBLEM SETİ
1. C'nin tasarımcıları, alt simge gerektirmemek karşılığında ne aldı?
menzil kontrolü?
2. Bunu yapan dillerde istisna işlemeye yönelik üç yaklaşımı tanımlayın.
için doğrudan destek sağlamaz.
3. PL/I ve Ada programlama dillerindeki ders kitaplarından
ilgili yerleşik istisna kümeleri. karşılaştırmalı bir değerlendirme yapmak
ikisi, hem eksiksizliği hem de esnekliği göz önünde bulundurarak.
4. ARM'den (1995), aşağıdaki durumlarda istisnaların nasıl gerçekleştiğini belirleyin.
randevu işlenir.
5. COBOL ile ilgili bir ders kitabından, istisna işlemenin nasıl yapıldığını belirleyin
COBOL programlarında.
6. İstisna işleme olanakları olmayan dillerde,
çoğu alt program, ayarlanabilen bir "hata" parametresi içerir.
"Tamam"ı temsil eden bir değer veya "hatayı" temsil eden başka bir değer
prosedürde.” Dilsel bir istisna işlemenin avantajı nedir?
Ada'nınki gibi tesis bu yöntem üzerinde var mı?
7. İstisna işleme olanakları olmayan bir dilde,
hata işleme prosedürü, her prosedür için bir parametre olarak
ele alınması gereken hataları tespit edin. Bunun ne gibi dezavantajları var
yöntem?
8. Problem 6 ve 7'de önerilen yöntemleri karşılaştırın.
düşünmek daha iyi ve neden?
9. C++' ın throw yan tümcesinin karşılaştırmalı bir analizini yazın ve
Java'nın yan tümcesini atar .
10. C++'ın istisna işleme olanaklarını Ada'nınkilerle karşılaştırın.
Sizce en esnek tasarım hangisi? Bu onu poz-
daha güvenilir programlar yazmak mümkün mü?
11. Aşağıdaki C++ iskelet programını düşünün:
sınıf Büyük {
int i;
yüzer f;
void fun1() fırlatma int {
. . .
denemek {
. . .
ben atmak ;
. . .
f atmak ;
. . .
}

Sayfa 689
668
Bölüm 14 İstisna İşleme ve Olay İşleme
yakalamak ( yüzer ) { . . . }
. . .
}
}
sınıf Küçük {
int j;
yüzer g;
void fun2() fırlatma şamandırası {
. . .
denemek {
. . .
denemek {
Büyük.fun1();
. . .
j atmak ;
. . .
g atmak;
. . .
}
yakalamak ( int ) { . . . }
. . .
}
yakalamak ( yüzer ) { . . . }
}
}
Dört atış ifadesinin her birinde , istisna nerede işlenir?
Not fun1 çağrılır FUN2 sınıf içinde Küçük .
12. Özel durum işleme yeteneklerinin ayrıntılı bir karşılaştırmasını yazın.
C++ ve Java'nınkiler.
13. MO üzerine bir kitap yardımıyla, aşağıdakilerin ayrıntılı bir karşılaştırmasını yazın.
makine öğreniminin ve Java'nın istisna işleme yetenekleri.
14. Fesih ve yeniden başlatma lehine argümanları özetleyin
devam modelleri.
PROGRAMLAMAALIŞTIRMALAR
1. Tape_Read bir prosedüre çağrıyı yeniden deneyen bir Ada kodu segmenti yazın ,
bir teyp sürücüsünden girişi okuyan ve Tape_Read_Error'ı yükseltebilen
istisna.
2. Üç alternatifi olan bir C++ işlevi yazdığınızı varsayalım.
gereksinimlerini karşılamaya yönelik yaklaşımlardır. İskelet versiyonunu yaz
bu işlevin, böylece ilk alternatif herhangi bir istisna ortaya çıkarırsa,

Sayfa 690
Programlama Alıştırmaları 669
ikincisi denenir ve ikinci alternatif herhangi bir istisna ortaya çıkarırsa,
üçüncüsü yürütülür. Kodu üç yöntem prosedürlermiş gibi yazın
adlı alt1 , alt2 ve alt3 .
3. Aralığındaki tamsayı değerlerinin bir listesini giren bir Java programı yazın.
-100'den 100'e klavyeden ve karelerinin toplamını hesaplar
giriş değerleri. sağlamak için bu program istisna işlemeyi kullanmalıdır.
giriş değerlerinin aralık içinde olduğunu ve yasal tamsayılar olduğunu,
karelerin toplamının standart bir Tamsayıdan daha büyük olma hatası
değişken depolayabilir ve dosyanın sonunu algılayabilir ve çıktıya neden olmak için kullanabilir
sonucun. Toplamın taşması durumunda, bir hata mesajı verilmelidir.
yazdırılır ve program sonlandırılır.
4. Programlama Alıştırması 3'ün spesifikasyonu için bir C++ programı yazın.
5. Programlama Alıştırması 3'ün belirtimi için bir Ada programı yazın.
6. revize kullanmak Bölüm 14.4.5.'te Java programı EOFException için
girişin sonunu tespit edin.
7. Bölüm 14.4.6'daki Java kodunu, içinde bir nihayet yan tümcesi kullanan yeniden yazın .
C++.

Sayfa 691
Bu sayfa bilerek boş bırakılmıştır

Sayfa 692
671
15.1 Giriş
15.2 Matematiksel Fonksiyonlar
15.3 Fonksiyonel Programlama Dillerinin Temelleri
15.4 İlk Fonksiyonel Programlama Dili: LISP
15.5 Şemaya Giriş
15.6 Ortak LISP
15.7 ML
15.8 Haskell
15.9 F#
15.10 Öncelikli Olarak Fonksiyonel Programlama Desteği
Zorunlu Diller
15.11 İşlevsel ve Zorunlu Dillerin Karşılaştırılması
15
Fonksiyonel Programlama
Diller

Sayfa 693
672
Bölüm 15 Fonksiyonel Programlama Dilleri
Bu bölüm, işlevsel programlamayı ve programlamanın bazı bölümlerini tanıtır.
yazılım geliştirmeye yönelik bu yaklaşım için tasarlanmış diller
ment. Matematiksel fonksiyonların temel fikirlerini gözden geçirerek başlıyoruz,
çünkü işlevsel diller onlara dayanır. Ardından, işlevsel bir pro-
dilbilgisi dili tanıtılır, ardından ilk işlevsel dile bir göz atılır,
LISP ve lambda tabanlı liste veri yapıları ve fonksiyonel sözdizimi
notasyon. Bir sonraki, biraz uzun bölüm, bir girişe ayrılmıştır.
Bazı ilkel işlevleri, özel biçimleri, işlevsel biçimleri ve
Şema'da yazılmış bazı basit işlev örnekleri. Daha sonra, kısa bir tanıtım sağlarız.
Common LISP, ML, Haskell ve F# ile ilgili bilgiler. Ardından, işlevsellik için desteği tartışırız.
bazı zorunlu dillerde görünmeye başlayan programlama. Bir bölüm
Aşağıdaki, işlevsel programlama dillerinin bazı uygulamalarını açıklar.
Son olarak, işlevsel ve zorunlu dillerin kısa bir karşılaştırmasını sunuyoruz.
15.1 Giriş
Bu kitabın önceki bölümlerinin çoğu, öncelikle
zorunlu programlama dilleri. arasında yüksek derecede benzerlik
emir kipi dilleri kısmen onların ortak temellerinden birinden doğar.
tasarım: Bölüm 1'de tartışıldığı gibi von Neumann mimarisi
diller toplu olarak, gelişmelerin ilerlemesi olarak düşünülebilir.
Fortran I olan temel modeli geliştirmek.
von Neumann mimarisi bilgisayarların verimli kullanımı. Her ne kadar impera-
çoğu programcı tarafından kabul edilebilir bir programlama stili
temeldeki mimariye olan yoğun bağımlılığı, bazıları tarafından bir
yazılım geliştirmeye yönelik alternatif yaklaşımlar üzerinde gereksiz kısıtlamalar.
Dil tasarımı için başka temeller de mevcuttur, bunlardan bazıları daha çok par-
verimli yürütme yerine özel programlama paradigmaları veya metodolojileri
belirli bir bilgisayar mimarisinde Ancak şimdiye kadar sadece nispeten küçük bir
programların az bir kısmı emirsiz dillerde yazılmıştır.
Matematiksel temellere dayanan fonksiyonel programlama paradigması
fonksiyonların en önemli zorunlu olmayan stillerinin tasarım temelidir.
Diller. Bu programlama stili, fonksiyonel programlama ile desteklenir.
Diller.
1977 ACM Turing Ödülü, John Backus'a ABD'deki çalışmaları nedeniyle verildi.
Fortran'ın gelişimi. Bu ödülün her alıcısı, aşağıdaki durumlarda bir konferans sunar:
ödül resmi olarak verilir ve ders daha sonra dergide yayınlanır.
ACM'nin İletişimi . Backus (1978) Turing Ödülü dersinde bir
tamamen işlevsel programlama dillerinin zorunlu olmaktan daha iyi olduğu durum
diller, çünkü daha okunabilir, daha güvenilir programlarla sonuçlanırlar.
mümkün ve doğru olma olasılığı daha yüksek. Argümanının püf noktası tamamen şuydu:
işlevsel programların hem geliştirme sırasında hem de sonrasında anlaşılması daha kolaydır.
çünkü büyük ölçüde ifadelerin anlamları, anlamlarından bağımsızdır.
bağlam (saf bir işlevsel programlama dilinin karakterize edici bir özelliği
ne ifadelerin ne de işlevlerin yan etkileri olmamasıdır).

Sayfa 694
15.2 Matematiksel Fonksiyonlar 673
Bu konuşmada, Backus (saf fonksiyonel dil, FP önerdi f unctional
p programlama), argümanını çerçevelemek için kullandı. dil yapmış olsa da
en azından yaygın kullanıma ulaşma açısından başarılı olamadı, fikri motive etti.
saf fonksiyonel programlama dilleri üzerine tartışma ve araştırma. Buradaki nokta
bazı tanınmış bilgisayar bilimcilerinin,
işlevsel programlama dillerinin geleneksel dillerden üstün olduğu kavramı
zorunlu diller, ancak bu çabalar açıkça yetersiz kalmıştır.
hedefler. Bununla birlikte, son on yılda, kısmen olgunlaşmanın yol açtığı
ML, Haskell, OCaml ve F# gibi yazılan fonksiyonel diller,
Fonksiyonel programlama dillerine ilgi ve kullanımda artış olmuştur.
İmperyal olarak yazılan programların temel özelliklerinden biri
diller, yürütme boyunca değişen duruma sahip olmalarıdır.
işlem. Bu durum, programın değişkenleri tarafından temsil edilir. yazar ve
Programın tüm okuyucuları, değişkenlerin kullanımlarını ve nasıl
programın durumu yürütme yoluyla değişir. Büyük bir program için bu
zor bir görev. Bu, zorunlu olarak yazılmış programlarla ilgili bir sorundur.
saf işlevsel bir dilde yazılmış bir programda bulunmayan dil,
bu tür programların ne değişkenleri ne de durumları vardır.
LISP, saf bir işlevsel dil olarak başladı, ancak kısa süre sonra bazı önemli bilgiler edindi.
yürütme verimliliğini artıran tant zorunlu özellikler. Hala en çok
işlevsel dillerin en azından tek olması anlamında önemlidir.
yaygın kullanıma kavuşmuştur. Bilgi temsili alanlarında hakimdir.
sentasyon, makine öğrenimi, akıllı eğitim sistemleri ve
konuşma. Ortak LISP, LISP'in 1980'lerin başlarındaki birkaç lehçesinin bir karışımıdır.
Scheme, LISP'nin küçük, statik kapsamlı bir lehçesidir. Şema yaygınlaştı
Fonksiyonel programlamayı öğretmek için kullanılır. Bazı üniversitelerde de kullanılmaktadır.
programlamaya giriş dersleri öğretmek.
Yazılan fonksiyonel programlama dillerinin geliştirilmesi, birincil
ily ML, Haskell, OCaml ve F#, kullanım alanlarının önemli ölçüde genişlemesine yol açmıştır.
şimdi işlevsel dillerin kullanıldığı bilgi işlem. Bu dillerin sahip olduğu gibi
olgunlaştıkça pratik kullanımları artıyor. Şu anda gibi alanlarda kullanılıyorlar.
veri tabanı işleme, finansal modelleme, istatistiksel analiz ve biyo-enformatik.
Bu bölümün amaçlarından biri, işlevselliğe bir giriş sağlamaktır.
Scheme'in özünü kullanarak, kasıtlı olarak zorunluluğunu dışarıda bırakarak programlama
özellikleri. Okuyucunun yazmasına izin vermek için Şema üzerinde yeterli materyal dahil edilmiştir
bazı basit ama ilginç programlar. Gerçek bir his elde etmek zor
bazı gerçek programlama deneyimi olmayan işlevsel programlama için, bu nedenle
bu şiddetle teşvik edilir.
15.2 Matematiksel Fonksiyonlar
Matematiksel bir işlev, etki alanı adı verilen bir kümenin üyelerinin eşlenmesidir.
aralık kümesi adı verilen başka bir kümeye ayarlayın. Bir fonksiyon tanımı şunları belirtir:
harita ile birlikte açık veya örtük olarak etki alanı ve aralık kümeleri
ping. Eşleme, bir ifadeyle veya bazı durumlarda bir tabloyla tanımlanır.

Sayfa 695
674
Bölüm 15 Fonksiyonel Programlama Dilleri
Fonksiyonlar genellikle etki alanı kümesinin belirli bir elemanına uygulanır.
fonksiyona bir parametre. Etki alanı kümesinin çapraz ürün olabileceğini unutmayın.
birkaç kümeden (birden fazla parametre olabileceğini yansıtan). bir işlev-
tion, aralık kümesinin bir öğesini verir.
Matematiksel fonksiyonların temel özelliklerinden biri şudur:
eşleme ifadelerinin değerlendirme sırası özyineleme ile kontrol edilir ve
sıralama ve yinelemeli tekrardan ziyade koşullu ifadeler
zorunlu programlama dilleri için ortak olan.
Matematiksel fonksiyonların bir diğer önemli özelliği de şudur:
yan etkileri yoktur ve herhangi bir dış değere bağlı olamazlar, her zaman
etki alanının belirli bir öğesini aralığın aynı öğesiyle eşleyin.
Bununla birlikte, zorunlu bir dilde bir alt program mevcut duruma bağlı olabilir.
birkaç yerel olmayan veya global değişkenin değerleri. Bu, caydırmayı zorlaştırır-
alt programın hangi değerleri üreteceğini ve hangi yan etkileri statik olarak benimseyin
belirli bir yürütmeye sahip olacaktır.
Matematikte hafızayı modelleyen değişken diye bir şey yoktur.
yer. Zorunlu programlama dillerinde fonksiyonlarda yerel değişkenler
fonksiyonun durumunu koruyun. Hesaplama değerlendirilerek gerçekleştirilir
programın durumunu değiştiren atama ifadelerindeki ifadeler. İçinde
matematikte, bir fonksiyonun durumu diye bir kavram yoktur.
Matematiksel bir fonksiyon, parametre(ler)ini bir değere (veya değerlere) eşler.
üretmek için bellekteki değerler üzerinde bir dizi işlem belirtmek yerine
değer.
15.2.1 Basit Fonksiyonlar
İşlev tanımları genellikle bir işlev adı olarak yazılır, ardından aşağıdakilerin bir listesi gelir:
parantez içindeki parametreler, ardından eşleme ifadesi. Örneğin,
küp(x) K x * x * x, burada x bir gerçek sayıdır
Bu tanımda, etki alanı ve aralık kümeleri gerçek sayılardır. Sembol
K, “olarak tanımlanır” anlamında kullanılır. x parametresi herhangi bir üyeyi temsil edebilir
etki alanı kümesinin bir parçasıdır, ancak değerlendirme sırasında belirli bir öğeyi temsil edecek şekilde sabitlenmiştir.
fonksiyon ifadesinin ifadesi. Bu, matematik parametrelerinin bir yoludur.
cal işlevleri, zorunlu dillerdeki değişkenlerden farklıdır.
İşlev uygulamaları, işlev adı ile eşleştirilerek belirtilir.
etki alanı kümesinin belirli bir öğesi. Aralık öğesi şu şekilde elde edilir:
etki alanı öğesi alt ile işlev eşleme ifadesinin değerlendirilmesi
parametrenin oluşumları için oluşturulmuştur. Bir kez daha, önemli
değerlendirme sırasında, bir işlevin eşlenmesinin hiçbir ilişkisiz içermediğine dikkat edin.
parametreler, burada bağlı parametre belirli bir değerin adıdır. Her
Bir parametrenin oluşumu, etki alanı kümesinden bir değere bağlıdır ve bir
değerlendirme sırasında sabittir. Örneğin, aşağıdaki değerlendirmeyi göz önünde bulundurun
küp(x):
küp (2.0) = 2.0 * 2.0 * 2.0 = 8

Sayfa 696
15.2 Matematiksel Fonksiyonlar 675
x parametresi değerlendirme sırasında 2.0'a bağlıdır ve
bağlı olmayan parametreler. Ayrıca x bir sabittir (değeri değiştirilemez)
değerlendirme sırasında.
Fonksiyonlar üzerine erken dönem teorik çalışmalar, bir fonksiyon tanımlama görevini birbirinden ayırdı.
işlevi adlandırmaktan çıkar. Alonzo tarafından tasarlanan Lambda gösterimi
Church (1941), isimsiz işlevleri tanımlamak için bir yöntem sağlar. bir lambda
ifade , bir fonksiyonun parametrelerini ve eşlemesini belirtir. lambda
ifade, isimsiz olan fonksiyonun kendisidir. Örneğin, şunu düşünün:
aşağıdaki lambda ifadesi:
(x)x * x * x
Church resmi bir hesaplama modeli tanımladı (işlev için resmi bir sistem)
tanım, işlev uygulaması ve özyineleme) lambda ifadeleri kullanarak. Bu
lambda hesabı denir . Lambda hesabı, yazılabilir veya yazılamaz.
Türlenmemiş lambda hesabı, işlevsel program için ilham kaynağı olarak hizmet eder.
ming dilleri.
Daha önce belirtildiği gibi, değerlendirmeden önce bir parametre herhangi bir üyeyi temsil eder.
etki alanı kümesinin, ancak değerlendirme sırasında belirli bir üyeye bağlıdır.
Belirli bir parametre için bir lambda ifadesi değerlendirildiğinde, ifade
bu parametreye uygulanacağı söylenir. Böyle bir uygulamanın mekaniği
herhangi bir fonksiyon değerlendirmesiyle aynıdır. Örnek lambda uygulaması
ifadesi aşağıdaki örnekteki gibi gösterilir:
((x)x * x * x)(2)
bu da 8 değeriyle sonuçlanır.
Lambda ifadeleri, diğer fonksiyon tanımları gibi, birden fazla fonksiyona sahip olabilir.
bir parametre.
15.2.2 Fonksiyonel Formlar
Daha yüksek dereceli bir işlev veya işlevsel biçim , bir
veya daha fazla parametre olarak işlev görür veya sonucu olarak bir işlev verir, ya da her ikisi.
Fonksiyonel formu yaygın bir tür fonksiyon bileşim vardır,
iki fonksiyonel parametre ve değeri ilk gerçek olan bir fonksiyon verir
saniyenin sonucuna uygulanan parametre işlevi. fonksiyon bileşimi
operatör olarak ° kullanılarak bir ifade olarak yazılır.
h K fg
örneğin, eğer
f ( x ) K x + 2
g ( x ) K 3 * x
o zaman h olarak tanımlanır
h ( x ) K f ( g ( x )) veya h ( x ) K (3 * x ) + 2

Sayfa 697
676
Bölüm 15 Fonksiyonel Programlama Dilleri
Tümüne uygula , tek bir işlevi parametre olarak alan işlevsel bir biçimdir.
eter. 1 Bir argüman listesine uygulanırsa, tümüne uygula, işlevsel parametrelerini uygular.
liste argümanındaki değerlerin her birine eter ve sonuçları bir listede toplar
veya sıra. Tümüne uygula ile gösterilir. Aşağıdaki örneği göz önünde bulundurun:
İzin vermek
h ( x ) K x * x
sonra
( h , (2, 3, 4)) verimler ( 4, 9, 16 )
Başka işlevsel biçimler de vardır, ancak bu iki örnek,
hepsinin temel özellikleri.
15.3 Fonksiyonel Programlama Dillerinin Temelleri
İşlevsel bir programlama dilinin tasarımının amacı,
matematiksel fonksiyonları mümkün olan en geniş ölçüde Bu, bir
yaklaşımlardan temelde farklı olan problem çözme yaklaşımı
zorunlu dillerle birlikte kullanılır. Zorunlu bir dilde, bir ifade
değerlendirilir ve sonuç temsil edilen bir hafıza konumunda saklanır.
Bir programda değişken olarak. Atama ifadelerinin amacı budur. Bu
durumunu temsil eden bellek hücrelerine gerekli dikkat
program, nispeten düşük seviyeli bir programlama metodolojisi ile sonuçlanır.
Derleme dilindeki bir program genellikle aşağıdakilerin sonuçlarını da depolamalıdır.
ifadelerin kısmi değerlendirmeleri. Örneğin, değerlendirmek için
( x + y )/( a - b )
( x + y ) değeri önce hesaplanır. Bu değer daha sonra saklanmalıdır
( a - b ) değerlendirilir. Derleyici, ara sonuçların depolanmasını gerçekleştirir
üst düzey dillerde ifade değerlendirmeleri. Ara depolama
sonuçlar hala gereklidir, ancak ayrıntılar programcıdan gizlenir.
Tamamen işlevsel bir programlama dili, değişkenleri veya
atama ifadeleri, böylece programcıyı ilgili endişelerden kurtarır.
programın bellek hücreleri veya durumu. Değişkenler olmadan, yinelemeli con-
yapılar değişkenler tarafından kontrol edildikleri için mümkün değildir. Tekrarlama gerekir
yineleme yerine özyineleme ile belirtilebilir. Programlar işlevdir
tanımlar ve işlev uygulama özellikleri ve yürütmeler şunlardan oluşur:
fonksiyon uygulamalarının değerlendirilmesi. Değişkenler olmadan, tamamen yürütülmesi
işlevsel programın operasyonel ve düz anlam anlamında hiçbir durumu yoktur.
anlambilim. Bir işlevin yürütülmesi, her zaman aynı sonucu verir.
aynı parametreler verilmiştir. Bu özelliğe referans şeffaflığı denir . o
tamamen işlevsel dillerin anlambilimini anlambilimden çok daha basit hale getirir.
zorunlu dillerin (ve aşağıdakileri içeren işlevsel dillerin) tikleri
1. Programlama dillerinde bunlara genellikle harita işlevleri denir .

Sayfa 698
15.4 İlk Fonksiyonel Programlama Dili: LISP 677
zorunlu özellikler). Ayrıca, her bir işlev farklı olabileceği için testi kolaylaştırır.
bağlamı için herhangi bir endişe olmaksızın ayrı ayrı test edilmiştir.
İşlevsel bir dil, bir dizi ilkel işlev, bir dizi işlev sağlar.
bu ilkel işlevlerden karmaşık işlevler oluşturmak için
işlev uygulama işlemi ve temsil etmek için bazı yapı veya yapılar
veri. Bu yapılar, hesaplanan parametreleri ve değerleri temsil etmek için kullanılır.
fonksiyonlara göre. İşlevsel bir dil iyi tanımlanmışsa, yalnızca göreceli bir dil gerektirir.
az sayıda ilkel fonksiyon.
Daha önceki bölümlerde gördüğümüz gibi, ilk fonksiyonel programlama lan-
guage, LISP, hem veri hem de kod için çok farklı bir sözdizimsel biçim kullanır.
emir kipi dillerinden. Ancak, birçok işlevsel dil
daha sonra tasarlananlar, kodları için zorunlu komuta benzer bir sözdizimi kullanır.
Diller.
Birkaç tamamen işlevsel dil olmasına rağmen, örneğin Haskell,
İşlevsel olarak adlandırılan dillerin çoğu bazı zorunlu özellikler içerir,
örneğin, atama ifadeleri gibi davranan değişken değişkenler ve yapılar.
İşlevsel dillerden kaynaklanan bazı kavram ve yapılar, örneğin
tembel değerlendirme ve anonim alt programlar olarak, şimdi kendi yolunu bulmuşlardır.
zorunlu olarak kabul edilen bazı diller.
Erken işlevsel diller genellikle inter-
preters, fonksiyonel programlama dillerinde yazılmış birçok program artık
derlenmiş.
15.4 İlk Fonksiyonel Programlama Dili: LISP
Birçok fonksiyonel programlama dili geliştirilmiştir. en eski ve
En yaygın kullanılanı, John tarafından geliştirilen LISP'dir (veya onun soyundan gelenlerden biridir).
McCarthy 1959'da MIT'de. İşlevsel dilleri LISP aracılığıyla incelemek biraz-
Fortran aracılığıyla zorunlu dilleri çalışmaya benzer: LISP ilk
işlevsel dil, ancak yarım yüzyıldır istikrarlı bir şekilde gelişmesine rağmen, hayır
long, işlevsel diller için en son tasarım kavramlarını temsil eder. Ek olarak,
ilk sürüm hariç, tüm LISP lehçeleri zorunlu dil içerir
zorunluluk stili değişkenler, atama ifadeleri ve yineleme gibi özellikler.
(Zorunlu stili değişkenler, değerleri değişebilen bellek hücrelerini adlandırmak için kullanılır.
program yürütme sırasında birçok kez değiştirin.) Buna ve biraz da olsa
garip form, orijinal LISP'nin torunları, temel
fonksiyonel programlama kavramlarıdır ve bu nedenle incelenmeye değerdir.
15.4.1 Veri Tipleri ve Yapıları
Orijinal LISP'de yalnızca iki veri nesnesi kategorisi vardı: atomlar
ve listeler. Liste öğeleri, ilk bölümün öğenin verileri olduğu çiftlerdir,
bu, bir atomun veya iç içe listenin bir göstergesidir. Bir çiftin ikinci kısmı
bir atom için bir işaretçi, başka bir element için bir işaretçi veya boş liste olabilir.
Öğeler, ikinci bölümlerle listelerde birbirine bağlanır. Atomlar ve listeler

Sayfa 699
678
Bölüm 15 Fonksiyonel Programlama Dilleri
zorunlu dillerin türleri olduğu anlamında türler değil. Aslında, orijinal
LISP, türsüz bir dildi. Atomlar, özdeşlik biçimindeki sembollerdir.
fiers veya sayısal değişmezler.
Bölüm 2'den, LISP'nin veri yapısı olarak orijinal olarak listeleri kullandığını hatırlayın.
çünkü liste işlemenin önemli bir parçası oldukları düşünülüyordu. Hatta olduğu gibi-
Bununla birlikte, LISP nadiren genel liste işlemlerini gerektirir.
listenin başlangıcı dışındaki konumlarda ekleme ve silme.
Listeler, LISP'de öğeleri parantez içinde sınırlandırılarak belirtilir.
Basit listelerin öğeleri atomlarla sınırlıdır.
(ABCD)
İç içe liste yapıları da parantez içinde belirtilir. Örneğin,
liste
(A (BC) D (E (FG)))
dört elementten oluşan bir listedir. Birincisi A atomudur ; ikincisi alt listedir (BC) ;
üçüncüsü D atomudur ; Dördüncü alt liste olan (E (FG)) olarak bulunur, onun
ikinci öğe alt liste (FG) .
Dahili olarak, bir liste genellikle her bir düğümün bağlı olduğu bağlantılı liste yapısı olarak saklanır.
biri düğümün verilerine başvurmak için diğeri oluşturmak için iki işaretçiye sahiptir.
bağlantılı liste. Bir listeye bir işaretçi tarafından ilk elemanına başvurulur.
İki örnek listemizin dahili temsilleri Şekil 15.1'de gösterilmektedir.
Bir listenin öğelerinin yatay olarak gösterildiğine dikkat edin. Listenin son elemanı
halefi yoktur, bu nedenle bağlantısı sıfırdır. Alt listeler aynı yapı ile gösterilir.
15.4.2 İlk LISP Yorumlayıcısı
LISP'in tasarımının asıl amacı, programların bir gösterimine sahip olmaktı.
gerektiğinde eklemelerle Fortran'a mümkün olduğunca yakın olacaktır. Bu
notasyon, meta-notasyon için M-notation olarak adlandırıldı. bir derleyici olması gerekiyordu
M-notasyonu ile yazılmış programları semantik olarak eşdeğere çevirecek olan
IBM 704 için ödünç makine kodu programları.
LISP'in geliştirilmesinin başlarında, McCarthy teşvik etmek için bir makale yazdı.
genel sembolik işlemeye bir yaklaşım olarak liste işleme. McCarthy
liste işlemenin hesaplanabilirliği incelemek için kullanılabileceğine inanıyordu.
zaman genellikle Turing makineleri kullanılarak incelenmiştir.
zorunlu hesaplama modeli. McCarthy, işlevsel
sembolik listelerin işlenmesi daha doğal bir hesaplama modeliydi.
Bantlara yazılan semboller üzerinde çalışan turing makineleri,
gönderilmiş hali Hesaplama çalışmasının ortak gereksinimlerinden biri
kişinin belirli hesaplanabilirlik özelliklerini kanıtlayabilmesi gerektiğidir.
Hangi hesaplama modeli kullanılıyorsa tüm sınıf. Bu durumuda
Turing makine modeli, evrensel bir Turing makinesi oluşturulabilir.
diğer Turing makinelerinin işlemlerini taklit edebilir. Bu konseptten

Sayfa 700
15.4 İlk Fonksiyonel Programlama Dili: LISP 679
değerlendirebilecek evrensel bir LISP işlevi oluşturma fikri geldi.
LISP'deki diğer herhangi bir işlev.
Evrensel LISP işlevi için ilk gereksinim, şu şekilde bir gösterimdi:
izin verilen işlevlerin, verilerin ifade edildiği şekilde ifade edilmesine izin verilir. bu
Bölüm 15.4.1'de açıklanan parantez içindeki liste gösterimi zaten
LISP verileri için kabul edildi, bu nedenle işlev için kurallar icat etmeye karar verildi
liste gösteriminde de ifade edilebilecek tanımlar ve işlev çağrıları.
İşlev çağrıları, orijinal olarak Cambridge olarak adlandırılan bir önek listesi formunda belirtildi.
Lehçe , 2 aşağıdaki gibi:
(işlev_adı bağımsız değişkeni 1 c bağımsız değişken n )
Örneğin, + iki veya daha fazla sayısal parametre alan bir işlevse,
aşağıdaki iki ifade sırasıyla 12 ve 20 olarak değerlendirilir :
(+ 5 7)
(+ 3 4 7 6)
Belirtmek için Bölüm 15.2.1'de açıklanan lambda gösterimi seçilmiştir.
fonksiyon tanımları. Bununla birlikte, bağlanmasına izin vermek için değiştirilmesi gerekiyordu.
2. Bu ad ilk olarak LISP'in erken geliştirilmesinde kullanılmıştır. isim seçildi çünkü
LISP listeleri, Polonyalı mantıkçı Jan Lukasiewicz tarafından kullanılan önek gösterimine benzer ve
çünkü LISP Cambridge, Massachusetts'te MIT'de doğdu. Bazıları şimdi aramayı tercih ediyor
gösterim Cambridge öneki .
Şekil 15.1
İç temsil
iki LISP listesinden
A
B
C
D
F
G
B
C
E
A
D
(ABCD)
(A (BC) D (E (FG)))

Sayfa 701
680
Bölüm 15 Fonksiyonel Programlama Dilleri
işlevlere diğer işlevler tarafından başvurulabilmesi için adlara işlevler
ve kendi başlarına. Bu isim bağlaması, aşağıdakilerden oluşan bir liste ile belirtilmiştir:
işlev adı ve aşağıdaki gibi lambda ifadesini içeren bir liste
( İşlev_adı (lambda ( arg 1 ... arg n ) ekspresyonunu ))
İşlevsel programlamaya önceden maruz kalmadıysanız,
isimsiz bir işlevi düşünmek bile garip. Ancak isimsiz fonksiyonlar
bazen işlevsel programlamada yararlıdır (aynı zamanda matematik ve
zorunlu programlama). 3 Örneğin, eylemi şu olan bir işlevi düşünün:
parametre listesine anında uygulama için bir fonksiyon üretmek. Profesyonel-
türetilmiş işlevin bir ada ihtiyacı yoktur, çünkü yalnızca bulunduğu noktada uygulanır.
yapı. Böyle bir örnek Bölüm 15.5.14'te verilmiştir.
Bu yeni gösterimde belirtilen LISP işlevlerine S-ifadeleri adı verildi,
için s ymbolic ifadeleri. Sonuç olarak, hem veri hem de kod olmak üzere tüm LISP yapıları,
S-ifadeleri olarak adlandırıldı. Bir S ifadesi, bir liste veya bir atom olabilir. Biz
genellikle S ifadelerine basitçe ifadeler olarak atıfta bulunur.
McCarthy başarılı bir şekilde evrensel bir işlev geliştirdi.
başka herhangi bir işlev. Bu işleve EVAL adı verildi ve kendisi şu şekildeydi:
ifade. LISP geliştiren AI Projesi'ndeki iki kişi,
Stephen B. Russell ve Daniel J. Edwards, bir
EVAL , bir LISP yorumlayıcısı olarak hizmet edebilir ve derhal böyle bir yapı oluşturdular.
bir uygulama (McCarthy ve diğerleri, 1965).
Bu hızlı, kolay ve beklenmedik uygulamanın birkaç önemli sonucu vardı.
uygulama. Öncelikle, bütün erken LISP uygulamaları kopyalanan EVAL ve vardı
dolayısıyla yorumlayıcı. İkincisi, M-notasyonunun tanımı,
LISP için planlanan programlama gösterimi, hiçbir zaman tamamlanmadı veya uygulanmadı.
S-ifadeleri LISP'in tek gösterimi haline geldi. Aynı kullanımı
veri ve kod için gösterimin önemli sonuçları vardır, bunlardan biri
Bölüm 15.5.14'te tartışılmıştır. Üçüncüsü, orijinal dil tasarımının çoğu
gibi dilde bazı garip özellikleri koruyarak etkili bir şekilde donduruldu
koşullu ifade formu ve hem boş liste için () kullanımı hem de
mantıksal yanlış
Görünüşe göre tesadüfi olan erken LISP sistemlerinin bir başka özelliği
dinamik kapsam kullanımıydı. Fonksiyonlar çevrede değerlendirildi.
arayanların mesajları. O zamanlar kimse kapsam belirleme hakkında fazla bir şey bilmiyordu ve
seçim için çok az düşünülmüş olabilir. Dinamik kapsam (önceki değeri)
1975'ten önce LISP'in çoğu lehçesi için kullanılırdı. Çağdaş lehçeler de
statik kapsam kullanın veya programcının statik ve
dinamik kapsam.
LISP için bir yorumlayıcı LISP'de yazılabilir. Böyle bir tercüman,
büyük bir program değildir, LISP'de LISP'nin operasyonel anlamını açıklar.
Bu, dilin anlamsal basitliğinin canlı kanıtıdır.
3. Zorunlu programlamada isimsiz alt programların da kullanımları vardır.

Sayfa 702
15.5 Şema 681'e Giriş
15.5 Şemaya Giriş
Bu bölümde, Scheme'in temel kısmını tanımlıyoruz (Dybvig, 2003). Sahibiz
Nispeten basit olduğu için seçilen Şema, kolejlerde popülerdir ve
üniversiteler ve Şema tercümanları bir süre için hazır (ve ücretsiz)
çok çeşitli bilgisayarlar. Bu bölümde açıklanan Şema sürümü
Şema 4'tür. Bu bölümün Şemanın yalnızca küçük bir bölümünü kapsadığını ve
Scheme'in zorunlu özelliklerinden hiçbirini içermez.
15.5.1 Planın Kökenleri
LISP'in bir lehçesi olan Scheme dili MIT'de geliştirilmiştir.
1970'lerin ortalarında (Sussman ve Steele, 1975). Küçük boyutu ile karakterizedir,
statik kapsam belirlemenin özel kullanımı ve işlevlerin birinci sınıf tüzel kişi olarak ele alınması
bağlar. Birinci sınıf varlıklar olarak, Şema işlevleri, ifadelerin değerleri olabilir,
listelerin öğeleri, parametre olarak geçirilen ve işlevlerden döndürülen. Erken
LISP sürümleri bu yeteneklerin hepsini sağlamadı.
Basit sözdizimi ve anlambilimi olan, esasen tipsiz küçük bir dil olarak,
Program, işlevsel dersler gibi eğitim uygulamaları için çok uygundur.
programlama ve ayrıca programlamaya genel girişler.
Aşağıdaki bölümlerdeki Şema kodunun çoğu yalnızca
LISP koduna dönüştürülecek küçük değişiklikler.
15.5.2 Şema Yorumlayıcısı
Etkileşimli moddaki bir Şema yorumlayıcısı, sonsuz bir okuma-değerlendirme-yazdırma döngüsüdür
(genellikle REPL olarak kısaltılır). tarafından yazılan bir ifadeyi tekrar tekrar okur.
kullanıcı (bir liste şeklinde), ifadeyi yorumlar ve sonucu görüntüler.
değer. Bu yorumlayıcı biçimi Ruby ve Python tarafından da kullanılır. İfade
EVAL işlevi tarafından yorumlanır . Değişmezler kendilerini değerlendirir. Yani, eğer
tercümana bir sayı yazın, o sadece sayıyı gösterir. İfade
ilkel işlevlere yapılan çağrılar şu şekilde değerlendirilir:
parametre ifadelerinin her biri belirli bir sırayla değerlendirilir. O zamanlar,
ilkel işlev parametre değerlerine uygulanır ve elde edilen
değer görüntülenir.
Elbette dosyalarda saklanan Scheme programları yüklenebilir ve
yorumlandı.
Şemadaki yorumlar, herhangi bir satırda noktalı virgül izleyen herhangi bir metindir.
15.5.3 İlkel Sayısal Fonksiyonlar
Şema, temel aritmetik işlemler için ilkel işlevleri içerir. Bunlar
Hangi + , - , * , ve / , eklenti için, çıkarma, çarpma ve bölme işlemlerini. * ve + sıfıra sahip olabilir
veya daha fazla parametre Eğer * hiçbir parametre verilir, bu döndüren 1 ; eğer + hiçbir verilir
parametreler, 0 döndürür . + tüm parametrelerini bir araya getirir. * hepsini çarpar

Sayfa 703
682
Bölüm 15 Fonksiyonel Programlama Dilleri
parametreleri bir arada. / ve - iki veya daha fazla parametreye sahip olabilir. durumda
çıkarma işleminde, ilk parametre hariç tümü ilk parametreden çıkarılır. Bölünme
çıkarma işlemine benzer. Bazı örnekler:
Şema'da çok sayıda başka sayısal işlev vardır.
Onları modülo , YUVARLAK , MAX , MIN , LOG , SIN ve SQRT . SQRT kareyi döndürür
parametrenin değeri negatif değilse, sayısal parametresinin kökü. Eğer
parametre negatifse, SQRT karmaşık bir sayı verir.
Şema'da, ayrılmış tüm kelimeler için büyük harfler kullandığımızı ve
önceden tanımlanmış fonksiyonlar Dilin resmi tanımı, orada olduğunu belirtir.
Bunlarda büyük ve küçük harf ayrımı yoktur. Ancak, bazıları
uygulamalar, örneğin DrRacket'in öğretim dilleri, daha düşük
ayrılmış kelimeler ve önceden tanımlanmış işlevler için durum.
Bir işlevin SQRT gibi sabit sayıda parametresi varsa, sayı
aramadaki parametrelerin sayısı bu numarayla eşleşmelidir. Aksi takdirde, tercüman
bir hata mesajı üretir.
15.5.4 Fonksiyonların Tanımlanması
Scheme programı, fonksiyon tanımlarının bir koleksiyonudur. Sonuç olarak, bilmek
Bu işlevlerin nasıl tanımlanacağı, en basit programı yazmanın ön koşuludur.
Şemada, isimsiz bir fonksiyon aslında LAMBDA kelimesini içerir ve
bir lambda ifadesi . Örneğin,
(LAMBDA(x)(*xx))
verilen sayısal parametrenin karesini döndüren isimsiz bir fonksiyondur.
Bu işlev, adlandırılmış işlevlerle aynı şekilde uygulanabilir:
gerçek parametreleri içeren bir listenin başına yerleştirmek. İçin
örneğin, aşağıdaki ifade 49 sonucunu verir :
((LAMBDA(x)(*xx)) 7)
Bu ifadede x , lambda ifadesi içinde bir bağlı değişken olarak adlandırılır .
Bu ifadenin değerlendirilmesi sırasında x , 7'ye bağlıdır . bağlı bir değişken
İfade
Değer
42
42
(* 3 7)
21
(+ 5 7 8)
20
(− 5 6)
-1
(− 15 7 2)
6
(− 24 (* 4 3))
12

Sayfa 704
15.5 Şema 683'e Giriş
gerçek bir parametre değerine bağlandıktan sonra ifadede asla değişmez
lambda ifadesinin değerlendirilmesi başladığında.
Lambda ifadeleri herhangi bir sayıda parametreye sahip olabilir. Örneğin, biz
aşağıdakilere sahip olabilir:
(LAMBDA (abcx) (+ (* axx) (* bx) c))
Scheme özel form işlevi DEFINE iki temel ihtiyaca hizmet eder
Şema programlamanın: bir adı bir değere bağlamak ve bir adı bir değere bağlamak
lambda ifadesi. Bir ismi bir değere bağlayan DEFINE formu,
o görünür DEFINE şart dil tarzı değişkenler oluşturmak için kullanılabilir.
Ancak, bu ad bağlamaları değişkenler değil, adlandırılmış değerler oluşturur.
DEFINE , farklı bir biçimde ( EVAL tarafından ) yorumlandığı için özel bir biçim olarak adlandırılır.
aritmetik fonksiyonlar gibi normal ilkellerden daha farklı
yakında gör.
DEFINE'ın en basit biçimi, bir adın değerine bağlamak için kullanılandır.
ifade. Bu form
(DEFINE sembol ifadesi )
Örneğin,
(DEFINE pi 3.14159)
(DEFINE iki_pi (* 2 pi))
Bu iki ifade Scheme yorumlayıcısına yazıldıysa ve ardından
pi yazıldığında 3.14159 sayısı görüntülenecektir; zaman two_pi yazıldığında,
6.28318 görüntülenecektir. Her iki durumda da görüntülenen sayılarda
burada gösterilenden daha fazla rakam.
Bu DEFINE formu, adlandırılmış bir sabitin bildirimine benzer.
zorunlu bir dilde. Örneğin, Java'da yukarıdakilerin eşdeğerleri
tanımlanan isimler aşağıdaki gibidir:
son şamandıra PI = 3.14159;
son şamandıra TWO_PI = 2.0 * PI;
Şemadaki isimler harflerden, rakamlardan ve özel karakterlerden oluşabilir.
parantez; bunlar büyük/küçük harfe duyarlı değildir ve bir rakamla başlamamalıdır.
DEFINE işlevinin ikinci kullanımı, bir lambda ifadesini şuna bağlamaktır:
bir isim. Bu durumda, lambda ifadesi, sözcüğü kaldırılarak kısaltılır.
LAMBDA . Bir adı lambda ifadesine bağlamak için DEFINE iki liste alır:
parametreler. İlk parametre, bir fonksiyon çağrısının prototipidir.
fonksiyon adı ve ardından resmi parametreler, bir listede birlikte. Saniye-
ond list, adın bağlanacağı bir ifade içerir. Genel
Bu tür a formu TANıMLAMAK olan 4
4. Aslında, DEFINE'ın genel biçimi, gövdesi olarak bir veya
daha fazla ifade, ancak çoğu durumda yalnızca bir tane dahil edilmiştir. Sim için sadece bir tane ekliyoruz.
nezaket aşkına.

Sayfa 705
684
Bölüm 15 Fonksiyonel Programlama Dilleri
(DEFINE (işlev_adı parametreleri )
( ifade )
)
Tabii ki, bu DEFINE formu basitçe adlandırılmış bir fonksiyonun tanımıdır.
Aşağıdaki örnek DEFINE çağrısı , ad karesini bir işleve bağlar.
bir parametre alan tional ifade:
(DEFINE (kare sayı) (* sayı sayı))
Yorumlayıcı bu işlevi değerlendirdikten sonra aşağıdaki gibi kullanılabilir.
(kare 5)
hangi 25 gösterir .
İlkel işlevler ile DEFINE arasındaki farkı göstermek için
özel form, aşağıdakileri göz önünde bulundurun:
(TANIMLA x 10)
DEFINE ilkel bir işlev olsaydı , EVAL'in bu ifade üzerindeki ilk eylemi
DEFINE öğesinin iki parametresini değerlendirmek olacaktır . Eğer x zaten değildi
bir değere bağlıysa, bu bir hata olur. Ayrıca, eğer x zaten olsaydı
tanımlansaydı, bu aynı zamanda bir hata olurdu , çünkü bu DEFINE yeniden düzenlemeye çalışacaktır.
iyi x , bu yasa dışıdır. Unutmayın, x bir değerin adıdır; bu bir değişken değil
zorunluluk anlamında.
Aşağıda başka bir fonksiyon örneği verilmiştir. uzunluğunu hesaplar
ikisinin uzunlukları verilen bir dik üçgenin hipotenüsü (en uzun kenar)
diğer taraflar.
(DEFINE (hipotenüs tarafı1 tarafı2)
(KARE(+(kenar kare1)(kare taraf2)))
)
Hipotenüsün daha önce tanımlanmış olan square kullandığına dikkat edin .
15.5.5 Çıkış Fonksiyonları
Şema birkaç basit çıktı işlevi içerir, ancak etkileşimle kullanıldığında
tive yorumlayıcı, Scheme programlarından gelen çoğu çıktı, normal çıktıdır.
üst düzey işlevlere EVAL uygulamasının sonuçlarını görüntüleyen yorumlayıcı .
Şema, şuna benzer biçimlendirilmiş bir çıktı işlevi, PRINTF içerir .
Printf C işlevi
Açık girdi ve çıktının saf işlevin parçası olmadığını unutmayın.
programlama modeli, çünkü giriş işlemleri program durumunu değiştirir ve
çıktı işlemlerinin yan etkileri vardır. Bunların hiçbiri saf bir sistemin parçası olamaz.
Fonksiyonel dil.

Sayfa 706
15.5 Şema 685'e Giriş
15.5.6 Sayısal Yüklem Fonksiyonları
Bir yüklem işlevi, bir Boole değeri döndüren işlevdir (bazı temsiller
doğru veya yanlış). Şema, aşağıdakiler için bir yüklem işlevleri koleksiyonu içerir:
sayısal veriler. Bunlar arasında şunlar vardır:
Tüm önceden tanımlanmış yüklem işlevlerinin adlarının şuna sahip olduğuna dikkat edin:
isimler için kelimeler soru işaretleri ile biter. Şemada, iki Boole değeri
olan #T ve #F (veya #t ve #f Bazı uygulamalarda boş kullanımı da,)
yanlış için liste. 5 Şema önceden tanımlanmış yüklem işlevleri boş listeyi döndürür,
() , yanlış için.
Bir liste Boolean olarak yorumlandığında, boş olmayan herhangi bir liste şu şekilde değerlendirilir:
doğru; boş liste false olarak değerlendirilir. Bu, yorumuna benzer
Boole değerleri olarak C'deki tamsayılar; sıfır, yanlış ve sıfır olmayan herhangi bir değer olarak değerlendirilir
doğru olarak değerlendirir.
Okunabilirlik açısından, bu örnekteki tüm örnek yüklem işlevlerimiz
bölüm dönüşü () yerine #F .
DEĞİL işlevi Boolean ifadenin mantığını ters çevirmek için kullanılır.
15.5.7 Kontrol Akışı
Şema, kontrol akışı için üç farklı yapı kullanır:
zorunlu dillerin seçim yapısı ve değerlendirmeye dayalı iki
Matematiksel fonksiyonlarda kullanılan kontrol.
IF adlı Şema iki yönlü seçici işlevinin üç parametresi vardır:
bir yüklem ifadesi, bir then ifadesi ve bir else ifadesi. IF'ye bir çağrı
forma sahip
(IF yüklemi then_expression else_expression )
5. Bazıları #T ve #F yerine doğru ve yanlış görüntüler.
İşlev
Anlam
=
Eşit
<>
Eşit değildir
>
daha büyük
<
Daha az
>=
Büyük veya eşit
<=
Küçük veya eşit
BİLE?
Çift sayı mı?
GARİP?
Tek sayı mı?
SIFIR?
sıfır mı

Sayfa 707
686
Bölüm 15 Fonksiyonel Programlama Dilleri
Örneğin,
(DEFINE (faktöriyel n)
(EĞER (<= n 1)
1
(* n (faktöriyel (− n 1)))
))
Şemanın çoklu seçiminin ( COND) şurada tartışıldığını hatırlayın :
Bölüm 8. Aşağıda, COND kullanan basit bir işlev örneği verilmiştir :
(DEFINE (artık? yıl)
(KOND
((SIFIR? (MODULO yıl 400)) #T)
((SIFIR? (MODULO yıl 100)) #F)
(BAŞKA (SIFIR? (MODULO yıl 4)))
))
Aşağıdaki alt bölümler, COND kullanımına ilişkin ek örnekler içerir .
Üçüncü Şema kontrol mekanizması, matematikte olduğu gibi kullanılan özyinelemedir.
ematics, tekrarı belirtmek için. Bölüm 15.5.10'daki örnek işlevlerin çoğu
özyinelemeyi kullanın.
15.5.8 Liste Fonksiyonları
LISP tabanlı programlama dillerinin daha yaygın kullanımlarından biri
liste işlemedir. Bu alt bölüm, anlaşma için Şema işlevlerini tanıtır.
listelerle. Scheme'in liste işlemlerinin kısaca tanıtıldığını hatırlayın.
Bölüm 6. Aşağıda, Şema'da liste işlemenin daha ayrıntılı bir tartışması bulunmaktadır.
Şema programları, fonksiyon uygulama fonksiyonu tarafından yorumlanır,
EVAL . İlkel bir işleve uygulandığında, EVAL önce parametreleri değerlendirir.
verilen fonksiyonun eterleri. Bu eylem, gerçek parametreler olduğunda gereklidir.
bir işlev çağrısında, sıklıkla görülen işlev çağrıları vardır.
Ancak bazı çağrılarda parametreler işlevden ziyade veri öğeleridir.
Referanslar. Bir parametre bir fonksiyon referansı olmadığında, açıkça
değerlendirilemez. Daha önce bununla ilgilenmemiştik, çünkü sayısal yan-
erals her zaman kendilerini değerlendirir ve işlev adlarıyla karıştırılamaz.
Bir atom ve bir liste olmak üzere iki parametresi olan bir fonksiyonumuz olduğunu varsayalım ve
fonksiyonun amacı verilen atomun cismin içinde olup olmadığını belirlemektir.
verilen liste. Ne atom ne de liste değerlendirilmeli; onlar gerçek veriler
incelenecek. Bir parametrenin değerlendirilmesini önlemek için önce parametre olarak verilir.
değişmeden basitçe döndüren ilkel QUOTE işlevine . bu
Aşağıdaki örnekler QUOTE'u göstermektedir :
(QUOTE A) A'yı döndürür
(QUOTE (ABC)) döndürür (ABC)

Sayfa 708
15.5 Şema 687'ye Giriş
Bu bölümün geri kalanında, çağrının ortak kısaltması
Basitçe alıntılanacak ifadeden önce yapılan QUOTE kullanılır.
kesme işaretiyle ( ' ). Bu durumda, yerine (tırnak (AB)) , '(AB) olacak
Kullanılmış.
QUOTE gerekliliği , temel doğası nedeniyle ortaya çıkar.
Şema (ve diğer LISP tabanlı diller): veri ve kod aynı
form. Bu, zorunlu dil programcılarına tuhaf gelse de,
biri tartışılan bazı ilginç ve güçlü süreçlerle sonuçlanır.
Bölüm 15.5.14'te.
OTOMOBİL , CDR ve EKSILERI fonksiyonları Bölüm 6. Aşağıdaki tanıtıldı
CAR ve CDR işlemlerinin ek örnekleri :
(CAR '(ABC)) A'yı döndürür
(CAR '((AB) CD)) döndürür (AB)
(CAR 'A) bir hata çünkü A bir liste değil
(CAR '(A)) A'yı döndürür
(CAR '()) bir hatadır
(CDR '(ABC)) (BC) değerini döndürür
(CDR '((AB) CD)) (CD) döndürür
(CDR 'A) bir hatadır
(CDR '(A)) döndürür ()
(CDR '()) bir hatadır
CAR ve CDR işlevlerinin adları en iyi ihtimalle özeldir. ori-
Bu isimlerin bir kısmı, LISP'in ilk uygulamasında yatmaktadır.
IBM 704 bilgisayar. 704'ün bellek sözcükleri, azalma olarak adlandırılan iki alana sahipti.
ve adres çeşitli işlenen adresleme stratejiler kullanılmıştır. Her biri
bu alanlar bir makine bellek adresi saklayabilir. 704 ayrıca iki
makine talimatları da adlandırılan ARAÇ ( C arasında indekiler bir a DRES parçası r egis-
ter) ve CDR ( C arasında indekiler d a ecrement parçası r egister), bu ekstre
ilişkili alanlar. İki işaretçiyi depolamak için iki alanı kullanmak doğaldı.
Bir liste düğümünün, böylece bir bellek kelimesinin bir düğümü düzgün bir şekilde depolayabilmesi için. Bunları kullanmak
sözleşmeler, 704'ün CAR ve CDR talimatları etkin liste sağladı
seçiciler. İsimler, LISP'nin tüm lehçelerinin ilkellerine taşındı.
Basit bir işlevin başka bir örneği olarak, düşünün
(DEFINE (ikinci a_list) (CAR (CDR a_list)))
Bu fonksiyon değerlendirildikten sonra aşağıdaki gibi kullanılabilir.
(ikinci '(ABC))
hangi B döndürür .
Şemada en sık kullanılan fonksiyonel kompozisyonlardan bazıları şunlardır:
tek işlevler olarak yerleşiktir. Örneğin, (CAAR x) , (CAR(CAR
x)) , (CADR x) eşdeğerdir (CAR (CDR x)) , ve () CADDAR x edilir

Sayfa 709
688
Bölüm 15 Fonksiyonel Programlama Dilleri
(CAR (CDR (CDR (CAR x)))) ile eşdeğerdir . Herhangi bir kombinasyonu A s ve
D 'ye kadar, dörde kadar , işlevin adındaki ' C ' ve ' R ' arasında yasaldır . Olarak
bir örnek olarak, aşağıdaki CADDAR değerlendirmesini göz önünde bulundurun :
(CADDAR '((AB (C) D) E)) =
(CAR (CDR (CDR (CAR '((AB (C) D) E))))) =
(CAR (CDR (CDR '(AB (C) D)))) =
(CAR (CDR '(B (C) D))) =
(ARAÇ '((C) D)) =
(C)
CONS için örnek çağrılar aşağıdadır :
(CONS 'A '()) (A) değerini döndürür
(EKSİ 'A'(BC)) döndürür (ABC)
(CONS '() '(AB)) döndürür (() AB)
(CONS '(AB) '(CD)) döndürür ((AB) CD)
Bu CONS işlemlerinin sonuçları Şekil 15.2'de gösterilmektedir. Not
bu cons olan, bir anlamda, ters CAR ve CDR . CAR ve CDR bir liste alır
ayrı ve CONS , verilen liste parçalarından yeni bir liste oluşturur. İki parametre-
için etreleri EKSİLERİNİ haline ARAÇ ve CDR yeni listenin. Böylece, eğer a_list ise
sonra bir liste
(EKSİLER (CAR a_list) (CDR a_list))
a_list ile aynı yapıya ve aynı öğelere sahip bir liste döndürür .
Yalnızca nispeten basit sorunlar ve tartışılan programlarla ilgilenmek
bu bölümde, iki atoma CONS'un kasıtlı olarak uygulanması pek olası değildir ,
yasal olmasına rağmen. Böyle bir uygulamanın sonucu noktalı bir çifttir, yani
Şema tarafından görüntülenme şekli nedeniyle adlandırılmıştır. Örneğin, düşünün
aşağıdaki çağrı:
(EKSİ 'A'B)
Bunun sonucu görüntülenirse, şu şekilde görünecektir:
(A.B)
Bu noktalı çift, bir atom ve bir işaretçi veya bir işaretçi yerine
ve bir işaretçi, bu hücrenin iki atomu var.
LIST , değişken sayıda parametreden bir liste oluşturan bir fonksiyondur.
eter. Şekilde gösterildiği gibi , iç içe CONS işlevlerinin kısa bir versiyonudur.
Takip etmek:
(LİSTE 'elma' portakal 'üzüm)

Sayfa 710
15.5 Şema 689'a Giriş
İadeler
(elma portakal üzümü)
Kullanılması EKSİLERİNİ , çağrı LİSTESİNDE şöyle yukarıda yazılır:
(EKSİLER 'elma (EKSİLER 'turuncu (EKSİLER 'üzüm '())))
15.5.9 Sembolik Atomlar ve Listeler için Yüklem Fonksiyonları
Şemanın üç temel yüklem işlevi vardır, EQ? , BOŞ? ve LİSTE? ,
sembolik atomlar ve listeler için.
EQ? işlevi, genellikle iki ifadeyi parametre olarak alır, ancak
iki sembolik atom parametresi ile kullanılır. Her iki parametrede de varsa #T döndürür.
aynı işaretçi değeri—yani, aynı atoma veya listeye işaret ederler; aksi halde,
#F döndürür . İki parametre sembolik atomlarsa, EQ? eğer yaparlarsa #T döndürür
Şekil 15.2
birkaç sonucu
EKSİ işlemleri
A
A
B
A
B
C
D
C
NIL
(EKSİLER 'A'())
(A)
(EKSİ 'A'(M.Ö.))
(ABC)
(EKSİLER '() '(AB))
(()AB)
A
B
(EKSİLER '(AB) '(CD))
((AB) CD'si)

Sayfa 711
690
Bölüm 15 Fonksiyonel Programlama Dilleri
aynı sembollerdir (çünkü Şema sembollerin kopyalarını oluşturmaz);
aksi halde #F . Aşağıdaki örnekleri göz önünde bulundurun:
(EQ? 'A 'A) # T'yi döndürür
(EQ? 'A 'B) # F'yi döndürür
(EQ? 'A'(AB)) #F değerini döndürür
(EQ? '(AB) '(AB)) #F veya #T döndürür
(EQ? 3.4 (+ 3 0.4)) #F veya #T döndürür
Dördüncü örneğin gösterdiği gibi, listeleri EQ ile karşılaştırmanın sonucu ? değil
tutarlı. Bunun nedeni, genellikle tamamen aynı olan iki listenin
bellekte kopyalanmaz. Scheme sistemi bir liste oluşturduğunda, kontrol eder.
zaten böyle bir liste olup olmadığını görmek için. Varsa, yeni liste başka bir şey değil
mevcut listeye bir işaretçiden daha fazla. Bu durumlarda, iki liste eşit olarak değerlendirilecektir.
tarafından EQ? . Bununla birlikte, bazı durumlarda, bir maddenin varlığını tespit etmek zor olabilir.
aynı liste, bu durumda yeni bir liste oluşturulur. Bu senaryoda, EQ? #F verir .
Son durum, eklemenin yeni bir değer üretebileceğini göstermektedir.
( EQ ile? ) 3.4'e eşit olmayacaksa veya zaten olduğunu fark edebilir
3.4 değerine sahiptir ve bunu kullanır, bu durumda EQ? işaretçiyi eskiye kullanacak
3.4 ve #T döndürün .
Gördüğümüz gibi, EQ? sembolik atomlar için çalışır ancak zorunlu değildir
sayısal atomlar için çalışır. = Sayısal atomlar ancak öncül eserleri
sembolik atomlar. Daha önce tartışıldığı gibi, EQ? ayrıca güvenilir bir şekilde çalışmıyor
parametreleri listeleyin.
Bazen iki atomu eşitlik açısından test edebilmek uygun olur.
sembolik mi yoksa sayısal mı oldukları bilinmiyor. Bu amaçla Şema
farklı bir yüklemi var, EQV? hem sayısal hem de sembolik üzerinde çalışan
atomlar. Aşağıdaki örnekleri göz önünde bulundurun:
(EQV? 'A 'A) # T'yi döndürür
(EQV? 'A 'B) #F değerini döndürür
(EQV? 3 3) # T'yi döndürür
(EQV? 'A 3) , # F'yi döndürür
(EQV? 3.4 (+ 3 0.4)) # T'yi döndürür
(EQV? 3.0 3) # F'yi döndürür
Son örneğin kayan nokta değerlerinin farklı olduğunu gösterdiğine dikkat edin.
tamsayı değerlerinden EQV? bir işaretçi karşılaştırması değil, bir değer karşılaştırmasıdır.
EQ kullanmanın birincil nedeni ? veya = EQV yerine ? mümkün olduğunda
yani EQ? ve = EQV'den daha hızlı ? .
LİSTE? yüklem işlevi , tek argümanı bir listeyse ve #T döndürür.
#F Aksi takdirde, aşağıdaki örneklerde olduğu gibi:
(LİSTE? '(XY)) # T'yi döndürür
(LİSTE? 'X) # F'yi döndürür
(LİSTE? '()) #T değerini döndürür

Sayfa 712
15.5 Şema 691'e Giriş
BOŞ? işlev, boş olup olmadığını belirlemek için parametresini test eder.
listeler ve varsa #T döndürür . Aşağıdaki örnekleri göz önünde bulundurun:
(NULL? '(AB)) #F değerini döndürür
(NULL? '()) #T değerini döndürür
(NULL? 'A) #F değerini döndürür
(NULL? '(())) #F değerini döndürür
Parametre boş liste olmadığı için son çağrı #F sonucunu verir . Daha doğrusu
tek bir öğe içeren bir liste, boş liste.
15.5.10 Örnek Şema Fonksiyonları
Bu bölüm, Şema'daki çeşitli fonksiyon tanımları örneklerini içerir.
Bu programlar basit liste işleme sorunlarını çözer.
Belirli bir listedeki belirli bir atomun üyelik problemini düşünün.
alt listeleri içermez. Böyle bir listeye basit liste denir . fonksiyon ise
adlı üye , aşağıdaki gibi kullanılabilir:
('B' (ABC) üyesi) # T'yi döndürür
('B' (ACDE) üyesi) # F'yi döndürür
Yineleme açısından düşünürsek, üyelik sorunu basitçe
verilen atomu ve verilen listenin tek tek öğelerini birer birer eşleştirin
herhangi bir sırayla, bir eşleşme bulunana veya içinde başka öğe kalmayana kadar
karşılaştırılacak liste. Benzer bir süreç yineleme kullanılarak gerçekleştirilebilir.
siyon. Fonksiyon, verilen atomu listenin CAR'ı ile karşılaştırabilir . Eğer onlar
eşleşme, #T değeri döndürülür. Onlar uyuşmuyorsa, ARAÇ listesinin gerektiği
yoksayılır ve arama listenin CDR'sinde devam eder . Bu yapılabilir
fonksiyonun kendisini liste parametresi olarak listenin CDR'si ile çağırması ve
bu özyinelemeli çağrının sonucunu döndür. Verilen atom olursa bu işlem sona erecektir.
listede bulunur. Atom listede yoksa, işlev sonunda olacaktır.
gerçek parametre olarak boş bir listeyle (kendi başına) çağrılır. O olay zorlamalı
#F döndürme işlevi . Bu süreçte, yinelemeden kurtulmanın iki yolu vardır.
sion: Bazı aramalarda liste boştur, bu durumda #F döndürülür veya bir
eşleşme bulunur ve #T döndürülür.
Toplamda, işlevde ele alınması gereken üç durum vardır: bir
boş girdi listesi, listenin atomu ile CAR'si arasında bir eşleşme veya yanlış bir
listenin atomu ile CAR'ı arasındaki eşleşme , bu da özyinelemeye neden olur.
aramak. Bu üçü , sonuncusu olmak üzere COND için üç parametredir .
ELSE yüklemi tarafından tetiklenen varsayılan durum . tam işlev
aşağıdaki: 6
6. Çoğu Scheme sistemi, üye adında bir işlev tanımlar ve kullanıcının yeniden tanımlamasına izin vermez.
o. Dolayısıyla okuyucu bu işlevi denemek isterse, başka bir adla tanımlanmalıdır.

Sayfa 713
692
Bölüm 15 Fonksiyonel Programlama Dilleri
(DEFINE (üye atm a_list)
(KOND
((NULL? a_list) #F)
((EQ? atm (CAR a_list)) #T)
(ELSE (üye atm (CDR a_list)))
))
Bu form, basit Şema listesi işleme işlevlerinin tipik bir örneğidir. Böyle bir işlevde
Listelerdeki veriler her seferinde bir öğe olarak işlenir. Bireysel
elemanlar CAR ile belirtilir ve özyineleme kullanılarak süreç devam ettirilir.
üzerinde CDR listenin.
CAR uygulandığı için boş testin eşit testten önce gelmesi gerektiğini unutmayın.
boş bir listeye bir hatadır.
Başka bir örnek olarak, iki tane olup olmadığını belirleme problemini ele alalım.
verilen listeler eşittir. İki liste basitse, çözüm nispeten kolaydır,
okuyucunun kullanmayabileceği bazı programlama teknikleri
tanıdık katılıyor. Basit karşılaştırma için bir yüklem işlevi, equalsimp
listeler burada gösterilir:
(DEFINE (equalsimp list1 list2)
(KOND
((BOŞ? liste1) (BOŞ? liste2))
((NULL? liste2) #F)
((EQ? (ARAÇ listesi1) (ARAÇ listesi2))
(equalsimp (CDR listesi1) (CDR listesi2)))
(BAŞKA #F)
))
COND öğesinin ilk parametresi tarafından işlenen ilk durum, ne zaman içindir?
ilk liste parametresi boş listedir. Bu, aşağıdaki durumlarda harici bir aramada meydana gelebilir:
ilk liste parametresi başlangıçta boştur. Özyinelemeli bir çağrı, CDR ' lerini kullandığından
iki parametre parametresi olarak listelenir, ilk liste parametresi boş olabilir
böyle bir çağrıda (ilk liste parametresi şimdi boşsa). İlk liste ne zaman
parametre boşsa, ikinci liste parametresinin kontrol edilip edilmediği kontrol edilmelidir.
o da boş. Eğer öyleyse, eşittirler (başlangıçta ya da CAR ' ler şu anda eşitti)
önceki tüm özyinelemeli çağrılar) ve NULL? doğru bir şekilde #T döndürür . ikinci liste ise
parametre boş değil, ilk liste parametresinden daha büyük ve #F olmalıdır
NULL olduğu gibi iade edilecek mi? .
Sonraki durum, birinci liste boşken ikinci listenin boş olmasıyla ilgilidir.
olumsuzluk. Bu durum, yalnızca ilk liste ikinciden daha uzun olduğunda ortaya çıkar.
İlk durum tüm örnekleri yakaladığından yalnızca ikinci liste test edilmelidir.
ilk listenin boş olması.
Üçüncü durum, iki kişi arasındaki eşitliği test eden özyinelemeli adımdır.
iki listedeki ilgili öğeler. Bunu CAR s'yi karşılaştırarak yapar.
iki boş olmayan listeden. Eşitlerse, iki liste şuna eşittir:
bu noktada, özyineleme her ikisinin de CDR'lerinde kullanılır . Bu durum iki olduğunda başarısız olur

Sayfa 714
15.5 Şema 693'e Giriş
eşit olmayan atomlar bulunur. Bu gerçekleştiğinde, işlemin devam etmesine gerek yoktur, bu nedenle
#F değerini döndüren varsayılan ELSE durumu seçilir .
Not olduğunu equalsimp parametre olarak listelerini beklediğini ve işletmek değil
parametrelerden biri veya her ikisi de atom ise doğru.
Genel listeleri karşılaştırma sorunu, şundan biraz daha karmaşıktır:
çünkü alt listeler karşılaştırma sürecinde tamamen izlenmelidir.
Bu durumda, özyinelemenin gücü benzersiz bir şekilde uygundur, çünkü
alt listelerin biçimi, verilen listelerinkiyle aynıdır. herhangi bir zaman
verilen iki listenin karşılık gelen öğeleri listelerdir, ayrılırlar
CAR ve CDR olmak üzere iki parçasına ayrılır ve üzerlerinde özyineleme kullanılır. Bu
böl ve yönet yaklaşımının kullanışlılığının mükemmel bir örneği. Eğer
verilen iki listenin karşılık gelen elemanları atomlardır, basitçe
EQ kullanılarak karşılaştırılabilir mi? .
Tam fonksiyonun tanımı aşağıdaki gibidir:
(DEFINE (eşit liste1 liste2)
(KOND
((NOT (LIST? list1)) (EQ? list1 list2))
(((LİSTE? liste2) DEĞİL) #F)
((BOŞ? liste1) (BOŞ? liste2))
((NULL? liste2) #F)
((eşit (CAR listesi1) (CAR listesi2))
(eşit (CDR listesi1) (CDR listesi2)))
(BAŞKA #F)
))
COND'nin ilk iki vakası , parametrelerden herhangi birinin bulunduğu durumu ele alır.
eters, bir liste yerine bir atomdur. Üçüncü ve dördüncü vakalar durum içindir.
bir veya her iki listenin boş olduğu yer. Bu davalar ayrıca sonraki davaların
uygulamaya çalışıyorsunuz ARAÇ boş listeye. Beşinci COND vakası en ilgi çekici olanıdır.
ing. Yüklem, listelerin CAR ' lerini parametre olarak içeren özyinelemeli bir çağrıdır . Eğer
bu özyinelemeli çağrı #T döndürür , ardından özyineleme listelerin CDR'lerinde tekrar kullanılır .
Bu algoritma, iki listenin herhangi bir derinliğe kadar alt listeler içermesine izin verir.
Bu eşitlik tanımı, yalnızca listelerde değil, herhangi bir ifade çiftinde çalışır.
eşit sistem yüklem işlevine eşdeğerdir EQUAL? . Bunu not et
EŞİT? sadece gerektiğinde kullanılmalıdır (gerçek para-
EQ'dan çok daha yavaş olduğu için mi bilinmiyor ? ve EQV? .
Yaygın olarak ihtiyaç duyulan bir diğer liste işlemi, yeni bir liste oluşturmaktır.
verilen iki liste bağımsız değişkeninin tüm öğelerini içerir. Bu genellikle
append adında bir Scheme işlevi olarak uygulandı . Sonuç listesi kon-
tekrarlanan kullanımı ile structed EKSİLERİNİ birinci liste argümanı unsurlarını yerleştirmek için
sonuç listesi haline gelen ikinci liste argümanına. Eylemi netleştirmek için
bir ekleme yapılması , aşağıdaki örnekleri göz önünde bulundurun:
(Ekleme '(AB)' (CDR)) döner (ABCDR)
(Ekleme '((AB) C)' (D (EF))) döner ((AB) CD (EF))

Sayfa 715
694
Bölüm 15 Fonksiyonel Programlama Dilleri
Tanımı , ekleme yapılması olan 7
(DEFINE (list1 list2'yi ekleyin)
(KOND
((BOŞ? liste1) liste2)
(ELSE (EKSİ (ARAÇ listesi1) (ek (CDR listesi1) listesi2)))
))
İlk COND durumu, özyinelemeli süreci sonlandırmak için kullanılır.
ilk argüman listesi boş, ikinci listeyi döndürüyor. ikinci durumda
( ELSE ), ARAÇ birinci parametre listesinin olan cons sonucu üzerine ed
ilk listenin CDR'sini ilk olarak geçen özyinelemeli çağrı tarafından döndürülür
parametre.
Aşağıdaki Şema işlevini düşünün, adı tahmin , bu işlevi kullanır.
Bu bölümde açıklanan üye işlevi. Daha önce ne yaptığını belirlemeye çalışın
takip eden açıklamayı okuyun. Parametrelerin basit listeler olduğunu varsayın.
(TANIMLA (tahmin listesi1 listesi2)
(KOND
((NULL? liste1) '())
((üye (ARAÇ listesi1) listesi2)
(EKSİLER (ARAÇ listesi1) (tahmin (CDR listesi1) listesi2)))
(ELSE (tahmin (CDR listesi1) listesi2))
))
tahmin , iki parametresinin ortak öğelerini içeren basit bir liste verir.
eter listeleri. Bu nedenle, parametre listeleri kümeleri temsil ediyorsa, tahmin şu şekilde bir liste hesaplar:
bu iki kümenin kesişimini temsil eder.
15.5.11 LET
LET , yerel bir kapsam oluşturan bir işlevdir (başlangıçta Bölüm 5'te açıklanmıştır).
adların geçici olarak ifadelerin değerlerine bağlı olduğu. Bu
genellikle ortak alt ifadeleri daha karmaşık olanlardan ayırmak için kullanılır.
ifadeler. Bu isimler daha sonra değerlendirmede kullanılabilir.
başka bir ifade, ancak LET içindeki yeni değerlere geri döndürülemezler . bu
aşağıdaki örnek LET kullanımını göstermektedir . a'nın köklerini hesaplar.
verilen ikinci dereceden denklem, köklerin gerçek olduğu varsayılarak. 8 matematiksel
ikinci dereceden denklemin gerçek (karmaşık yerine) köklerinin tanımları
ax 2 + bx + c aşağıdaki gibidir: root1 = (-b + sqrt(b 2 - 4ac))/2a ve
root2 = (-b - sqrt(b 2 - 4ac))/2a
7. Üye durumunda olduğu gibi, bir kullanıcı genellikle append adında bir fonksiyon tanımlayamaz.
8. Scheme'in bazı sürümleri, veri türü olarak "karmaşık" içerir ve aşağıdakilerin köklerini hesaplar.
denklem, gerçek veya karmaşık olmalarına bakılmaksızın.

Sayfa 716
15.5 Şema 695'e Giriş
(TANIMLA (kuadratik_kökler abc)
(İZİN VERMEK (
(root_part_over_2a
(/ (SQRT (- (* bb) (* 4 ac))) (* 2 a)))
(minus_b_over_2a (/ (− 0 b) (* 2 a)))
)
(LİSTE (+ minus_b_over_2a root_part_over_2a)
(− minus_b_over_2a root_part_over_2a))
))
Bu örnek , listeyi oluşturan iki değerin listesini oluşturmak için LIST'i kullanır .
sonuç.
Çünkü bir LET yapısının ilk bölümünde bağlı isimler olamaz.
aşağıdaki ifadede değişti, yerel değişkenlerle aynı değiller
zorunlu bir dilde bir blokta. Hepsi metinsel olarak ortadan kaldırılabilir
ikame.
LET aslında bir parametreye uygulanan LAMBDA ifadesinin kısaltmasıdır .
Aşağıdaki iki ifade eşdeğerdir:
(LET ((alfa 7))(* 5 alfa))
((LAMBDA (alfa) (* 5 alfa)) 7)
İlk ifadede 7 , LET ile alfaya bağlanır ; ikincisinde, 7 bağlı
için alfa parametresi ile LAMBDA ekspresyonu.
15.5.12 Şemada Kuyruk Özyinelemesi
Bir işlev, özyinelemeli çağrısı işlevdeki son işlemse kuyruk özyinelemelidir.
tion. Bu, özyinelemeli çağrının dönüş değerinin dönüş değeri olduğu anlamına gelir.
işleve özyinelemeli olmayan çağrının. Örneğin, üye işlevi
Burada tekrarlanan Bölüm 15.5.10, kuyruk özyinelemelidir.
(DEFINE (üye atm a_list)
(KOND
((NULL? a_list) #F)
((EQ? atm (CAR a_list)) #T)
(ELSE (üye atm (CDR a_list)))
))
Bu işlev, yinelemeyi kullanmak için bir derleyici tarafından otomatik olarak dönüştürülebilir,
özyinelemeli biçiminden daha hızlı yürütme ile sonuçlanır.
Ancak, yineleme için özyinelemeyi kullanan birçok işlev kuyruk değildir.
özyinelemeli. Verimlilikle ilgilenen programcılar keşfetti
Bu işlevlerden bazılarını kuyruk özyinelemeli olacak şekilde yeniden yazmanın yolları. Bir
Bunun örneği, bir biriktirme parametresi ve bir yardımcı işlev kullanır. olarak

Sayfa 717
696
Bölüm 15 Fonksiyonel Programlama Dilleri
bu yaklaşımın bir örneği olarak, Bölüm 15.5.7'deki faktöriyel fonksiyonu göz önünde bulundurun,
burada tekrarlanan:
(DEFINE (faktöriyel n)
(EĞER (<= n 1)
1
(* n (faktöriyel (− n 1)))
))
Bu fonksiyonun son işlemi çarpma işlemidir. işlev çalışır
çarpılacak sayıların listesini oluşturarak ve ardından
özyineleme sonucu üretmek için gevşerken çarpmalar. bunların her biri
sayılar, işlevin etkinleştirilmesiyle oluşturulur ve her biri bir
aktivasyon kaydı örneği. Özyineleme gevşedikçe sayılar çok-
birlikte uçtu. Birkaç yinelemeli çağrıdan sonra yığının gösterildiğini hatırlayın.
Bölüm 9'daki faktöriyel Bu faktöriyel fonksiyon, yardımcı bir fonksiyon ile yeniden yazılabilir.
kısmi faktöriyel toplamak için bir parametre kullanan yardımcı işlev.
Kuyruk özyinelemeli olan yardımcı işlev de faktöriyel parametresini alır .
Bu işlevler aşağıdaki gibidir:
(DEFINE (facthelper n factpartial)
(EĞER (<= n 1)
gerçek kısmi
(facthelper (− n 1) (* n factkısmi))
))
(DEFINE (faktöriyel n)
(yardımcı n 1)
)
Bu işlevlerle, özyinelemeli aramalar sırasında sonuç hesaplanır.
özyineleme gevşedikçe. Çünkü aktivasyonda faydalı bir şey yok
vakaları kaydedin, bunlar gerekli değildir. Kaç özyinelemeli çağrı olursa olsun
istendiğinde, yalnızca bir etkinleştirme kaydı örneği gereklidir. Bu
kuyruk özyinelemeli sürüm, kuyruk özyinelemeli olmayan sürümden çok daha verimli.
Şema dili tanımı, Şema dilinin işlenmesini gerektirir.
sistemler, bu özyinelemeyi yineleme ile değiştirmek için tüm özyinelemeli işlevleri dönüştürür.
tion. Bu nedenle, en azından verimlilik adına, işlevleri tanımlamak önemlidir.
yinelemeyi kuyruk özyinelemeli olarak belirtmek için özyinelemeyi kullanan. Bazı optimizasyon
bazı işlevsel diller için derleyiciler, bazılarının dönüşümlerini bile gerçekleştirebilir.
kuyruk özyinelemeli olmayan işlevlerden eşdeğer kuyruk özyinelemeli işlevlere ve ardından kod
bu işlevler, yineleme için özyineleme yerine yinelemeyi kullanır.
15.5.13 Fonksiyonel Formlar
Bu bölüm, iki yaygın matematiksel fonksiyonel formu tanımlar.
Şema tarafından sağlanır: kompozisyon ve herkese uygulanır. Her ikisi de matematiksel olarak
Bölüm 15.2.2'de tanımlanmıştır.

Sayfa 718
15.5 Şema 697'ye Giriş
15.5.13.1 Fonksiyonel Bileşim
Fonksiyonel kompozisyon, organizma tarafından sağlanan tek ilkel fonksiyonel formdur.
orijinal LISP. Şema da dahil olmak üzere sonraki tüm LISP lehçeleri ayrıca şunları sağlar:
o. Bölüm 15.2.2'de belirtildiği gibi, fonksiyon kompozisyonu fonksiyonel bir formdur.
parametre olarak iki işlevi alır ve önce aşağıdakileri uygulayan bir işlev döndürür:
parametresine ikinci parametre işlevi ve ardından ilk parametreyi uygular
işlevi, ikinci parametre işlevinin dönüş değerine dönüştürür. Başka bir deyişle,
fonksiyon h bileşimi fonksiyonudur f ve g ise h (x) = F (g (x)) . İçin
örnek, aşağıdaki örneği göz önünde bulundurun:
(TANIMLA (gx) (* 3 x))
(TANIMLA (fx) (+ 2 x))
Şimdi f ve g'nin fonksiyonel bileşimi aşağıdaki gibi yazılabilir:
(DEFINE (hx) (+ 2 (* 3 x)))
Şema'da, fonksiyonel kompozisyon fonksiyonu oluşturma yazılabilir
aşağıdaki gibi:
(DEFINE (fg oluştur) (LAMBDA (x)(f (gx))))
Örneğin, aşağıdakilere sahip olabiliriz:
((CAR CDR'yi oluşturun) '((ab) cd))
Bu çağrı c sonucunu verir . Bu, daha az verimli olsa da bir alternatiftir.
CADR . Şimdi oluşturmak için başka bir çağrı düşünün :
((CDR ARABA oluştur) '((ab) cd))
Bu çağrı (b) sonucunu verir . Bu, CDAR'a bir alternatiftir .
Compose kullanımına başka bir örnek olarak aşağıdakileri göz önünde bulundurun:
(DEFINE (üçüncü a_list)
((CAR oluştur (CDR CDR oluştur)) a_list))
Bu, CADDR'ye bir alternatiftir .
15.5.13.2 Tümüne Uygulanan İşlevsel Form
İşlevsel programlama dilinde sağlanan en yaygın işlevsel biçimler
ölçüler, matematiksel tüm işlevsel formların varyasyonlarıdır. En basit
Bunlardan biri map , iki parametreye sahiptir: bir işlev ve bir liste. haritayı uygular

Sayfa 719
698
Bölüm 15 Fonksiyonel Programlama Dilleri
verilen listenin her elemanına verilen fonksiyon ve sonuçların bir listesini döndürür
bu uygulamalardan. Haritanın bir Şema tanımı aşağıdaki gibidir: 9
(DEFINE (harita eğlencesi a_list)
(KOND
((NULL? a_list) '())
(BAŞKA (EKSİLER (eğlenceli (CAR a_list))
(harita eğlencesi (CDR a_list))))
))
Karmaşık bir işlevsel biçimi ifade eden basit map biçimine dikkat edin.
map kullanımına bir örnek olarak, bir haritanın tüm öğelerini istediğimizi varsayalım.
liste küplü. Bunu aşağıdakilerle başarabiliriz:
(harita (LAMBDA (sayı) (* sayı num)) '(3 4 2 6))
Bu çağrı döner (27 64 8 216) .
Bu örnekte, mapcar'ın ilk parametresinin bir LAMBDA olduğunu unutmayın.
ifade. Ne zaman EVAL değerlendirir LAMBDA ifade, bir fonksiyonlarda oluşturur
ad olması dışında önceden tanımlanmış herhangi bir işlevle aynı forma sahip olan
az. Örnek ifadede, bu isimsiz fonksiyon hemen uygulanır.
parametre listesinin her bir öğesine ve sonuçlar bir listede döndürülür.
15.5.14 Kod Oluşturan İşlevler
Programların ve verilerin aynı yapıya sahip olması,
programları oluşturmak. Scheme yorumlayıcısının adında bir işlev kullandığını hatırlayın.
EVAL . Scheme sistemi , yazılan her ifadeye EVAL uygular.
Etkileşimli yorumlayıcıdaki Şema isteminde veya bir programın parçası
yorumlandı. EVAL fonksiyonu da Şema programları tarafından doğrudan çağrılabilir.
Bu, bir Scheme programının ifadeler ve çağrılar oluşturma olasılığını sağlar.
onları değerlendirmek için EVAL . Bu, Scheme'e özgü bir şey değildir, ancak
ifadelerinin basit biçimleri, uygulama sırasında bunları oluşturmayı kolaylaştırır.
Bu sürecin en basit örneklerinden biri sayısal atomları içerir. Hatırlamak
Bu Şema, herhangi bir sayıda sayısal alan alan + adlı bir işlev içerir .
atomları argüman olarak kullanır ve toplamlarını döndürür. Örneğin, (+ 3 7 10 2)
22 döndürür .
Problemimiz şu: Diyelim ki bir programda bir listemiz var.
sayısal atomların toplamına ihtiyaç duyar. + direkt olarak listeye uygulayamıyoruz ,
çünkü + , sayısal atomların bir listesini değil, yalnızca atomik parametreleri alabilir. Biz
tabii ki, listenin CAR'ını tekrar tekrar ekleyen bir fonksiyon yazabilirdi .
Listeyi gözden geçirmek için özyinelemeyi kullanarak CDR'sinin toplamı . Böyle bir işlev aşağıdaki gibidir:
(DEFINE (ekleyici a_list)
(KOND
9. Üyede olduğu gibi harita, kullanıcılar tarafından yeniden tanımlanamayan önceden tanımlanmış bir fonksiyondur.

sayfa 720
15.6 Ortak LISP 699
((NULL? a_list) 0)
(ELSE (+ (CAR a_list) (toplayıcı (CDR a_list))))
))
Aşağıda, özyinelemeli çağrılarla birlikte toplayıcıya bir örnek çağrı verilmiştir ve
İadeler:
(toplayıcı '(3 4 5))
(+ 3 (toplayıcı (4 5)))
(+ 3 (+ 4 (toplayıcı (5))))
(+ 3 (+ 4 (+ 5 (toplayıcı ()))))
(+ 3 (+ 4 (+ 5 0)))
(+ 3 (+ 4 5))
(+ 3 9)
(12)
Soruna alternatif bir çözüm, oluşturan bir işlev yazmaktır.
uygun parametre formlarıyla +'ya bir çağrı . Bu, CONS kullanılarak yapılabilir
atoma sahip olması dışında parametre listesiyle aynı olan yeni bir liste oluşturmak için
+ başlangıcına eklenir. Bu yeni liste daha sonra ibraz edilebilir EVAL için
aşağıdaki gibi değerlendirme:
(DEFINE (ekleyici a_list)
(KOND
((NULL? a_list) 0)
(ELSE (Değerlendirme (CONS '+ a_list)))
))
O Not + işlevin adı önlemek için alıntılanmıştır EVAL bunu değerlendirirken gelen
CONS değerlendirmesinde . Aşağıda, bu yeni sürüme bir örnek çağrı verilmiştir.
adder , EVAL çağrısı ve dönüş değeriyle birlikte:
(toplayıcı '(3 4 5))
(Değerlendirme (+ 3 4 5)
(12)
Scheme'in önceki tüm sürümlerinde, EVAL işlevi, ifadesini değerlendirdi.
programın en dış kapsamında. Scheme'in sonraki sürümleri, başlangıç
Şema 4 ile, içindeki kapsamı belirten EVAL için ikinci bir parametre gerektirir .
hangi ifadenin değerlendirileceği. Basitlik adına, kapsamı bıraktık
parametre örneğimizin dışındadır ve burada kapsam adlarını tartışmıyoruz.
15.6 Ortak LISP
Ortak LISP (Steele, 1990), özellikleri birleştirmek amacıyla oluşturulmuştur.
Scheme de dahil olmak üzere LISP'in 1980'lerin başlarındaki birkaç lehçesini tek bir dil halinde
ölçü. Bir tür dil birliği olarak oldukça geniş ve karmaşıktır,

Sayfa 721
700
Bölüm 15 Fonksiyonel Programlama Dilleri
bu açıdan C++ ve C# ile benzerdir. Bununla birlikte, temeli orijinal LISP'dir,
bu yüzden sözdizimi, ilkel işlevleri ve temel doğası bundan gelir.
dilim.
Common LISP'de yazılmış faktöriyel fonksiyon aşağıdadır:
(DEFUN faktöriyel (x)
(EĞER (<= n 1)
1
(* n faktöriyel (− n 1)))
))
Bu işlevin yalnızca ilk satırı sözdizimsel olarak Scheme sürümünden farklıdır.
aynı işleve sahip.
Common LISP'in özelliklerinin listesi uzundur: çok sayıda veri
kayıtlar, diziler, karmaşık sayılar ve karakterler dahil olmak üzere türler ve yapılar
ter dizeleri; güçlü giriş ve çıkış işlemleri; ve bir paket formu
işlev ve veri koleksiyonlarını modüler hale getirmek ve ayrıca erişim sağlamak için
kontrol. Ortak LISP, bazı zorunlu yapıların yanı sıra bazı
değişebilir tipler
Dinamik kapsam belirlemenin sağladığı zaman zaman esnekliği de kabul etmek
statik kapsam belirlemenin basitliği olarak, Common LISP her ikisine de izin verir. Varsayılan
değişkenler için kapsam belirleme statiktir, ancak bir değişkeni "özel" olarak bildirerek
değişken dinamik olarak kapsamlı hale gelir.
Makrolar genellikle dili genişletmek için Common LISP'de kullanılır. Aslında,
önceden tanımlanmış işlevlerden bazıları aslında makrolardır. Örneğin, DOLIST ,
Bir değişken ve bir liste olmak üzere iki parametre alan bir makrodur. Örneğin,
aşağıdakileri göz önünde bulundur:
(DOLIST (x '(1 2 3)) (x yazdır))
Bu, aşağıdakileri üretir:
1
2
3
NIL
NIL burada DOLIST'in dönüş değeridir .
Makrolar etkisini iki adımda oluşturur: İlk olarak makro genişletilir. İkinci,
LISP kodu olan genişletilmiş makro değerlendirilir. Kullanıcılar tanımlayabilir
DEFMACRO ile kendi makrolarınızı oluşturun .
Ortak LISP geri alıntı operatörü ( ` ), Scheme'in QUOTE ' sine benzer ,
parametrenin bazı bölümleri, önlerine eklenerek alıntılanmayabilir, ancak
virgül. Örneğin, aşağıdaki iki örneği göz önünde bulundurun:
`(a (* 3 4) c)

Sayfa 722
15.7 ML 701
Bu ifade (a (* 3 4) c) olarak değerlendirilir . Ancak, aşağıdakiler
ifade:
`(a ,(* 3 4) c)
değerlendirir (12 c) .
LISP uygulamalarının , dönüştürücü olarak adlandırılan okuyucu adı verilen bir ön ucu vardır.
LISP programlarının metni bir kod gösterimine dönüştürülür. Ardından, makro çağırır
kod temsili, kod temsillerine genişletilir. Çıktı
bu adımın ardından ya yorumlanır ya da makine diline derlenir
ana bilgisayarın veya belki de inter-
taklit. Orada makro adında özel bir türüdür okuyucu makrolar veya makro okumak ,
bir LISP dil işlemcisinin okuyucu aşaması sırasında genişletilir. A
okuyucu makrosu, belirli bir karakteri bir LISP kodu dizisine genişletir. Sınav için-
ple, LISP'deki kesme işareti, QUOTE çağrısına genişleyen bir okuma makrosudur .
Kullanıcılar, diğer stenografi yapıları oluşturmak için kendi okuyucu makrolarını tanımlayabilir.
Ortak LISP ve diğer LISP tabanlı diller bir sembol verisine sahiptir.
tip. Ayrılmış kelimeler, T ve T gibi kendilerini değerlendiren sembollerdir.
NIL . Teknik olarak, semboller ya bağlıdır ya da ilişkisizdir. Parametre sembolleri
fonksiyon değerlendirilirken bağlanır. Ayrıca, isimler olan semboller
zorunlu-tarzı değişkenler ve atanmış değerler bağlıdır. Diğer
semboller sınırsızdır. Örneğin, aşağıdaki ifadeyi göz önünde bulundurun:
(LİSTE '(ABC))
A , B ve C sembolleri bağsızdır. Ruby'nin de bir sembol verisine sahip olduğunu hatırlayın
tip.
Bir anlamda, Şema ve Ortak LISP karşıttır. Şema çok daha küçük
ve kısmen statik kapsam belirlemenin özel kullanımı nedeniyle anlamsal olarak daha basit,
aynı zamanda programlama öğretmek için kullanılmak üzere tasarlandığından,
Ortak LISP'in ticari bir dil olması gerekiyordu. Ortak LISP vardır
diğerlerinin yanı sıra AI uygulamaları için yaygın olarak kullanılan bir dil olmayı başardı.
alanlar. Şema ise daha çok üniversite derslerinde kullanılmaktadır.
fonksiyonel programlama Ayrıca işlevsel bir ağ olarak çalışılması daha olasıdır.
Nispeten küçük boyutu nedeniyle guage. Common'ın önemli bir tasarım hedefi
LISP'in büyük bir dil olmasına neden olan, onu uyumlu hale getirme arzusuydu.
türetildiği LISP lehçelerinden birkaçı ile.
Ortak LISP Nesne Sistemi (CLOS) (Paepeke, 1993) geliştirildi
1980'lerin sonlarında Common LISP'in nesne yönelimli bir versiyonu olarak. Bu dil
diğer yapıların yanı sıra genel işlevleri ve çoklu kalıtımı destekler.
15.7 ML
ML (Milner ve diğerleri, 1990), statik kapsamlı bir işlevsel programlama dilidir.
Şema gibi. Ancak, LISP ve Scheme dahil lehçelerinden farklıdır.
bir dizi önemli yolla. Önemli bir fark, ML'nin bir

Sayfa 723
702
Bölüm 15 Fonksiyonel Programlama Dilleri
güçlü bir şekilde yazılmış dil, oysa Scheme esasen tipsizdir. ML'nin türü var
işlev parametreleri için bildirimler ve işlevlerin dönüş türleri
tür çıkarımı nedeniyle genellikle kullanılmazlar. Her değişkenin türü
ve ifade statik olarak belirlenebilir. ML, diğer fonksiyonel programlar gibi-
ming dilleri, emredici diller anlamında değişkenlere sahip değildir.
İçindeki değişkenlerin adlarının görünümüne sahip tanımlayıcıları vardır.
zorunlu diller. Ancak, bu tanımlayıcılar en iyi isim olarak düşünülür.
değerler için. Bir kez ayarlandıktan sonra değiştirilemezler. Adlandırılmış sabitler gibidirler
Java'daki son bildirimler gibi zorunlu dillerin . ML tanımlayıcıları
sabit türleri vardır—herhangi bir tanımlayıcı, herhangi bir türün değerinin adı olabilir.
Değerlendirme ortamı adı verilen bir tablo , tümünün adlarını örtük olarak saklar.
ve türleriyle birlikte bir programda açıkça belirtilen tanımlayıcılar. Bu
çalışma zamanı sembol tablosu gibi. Bir tanımlayıcı, örtük olarak veya dolaylı olarak bildirildiğinde
açıkça, değerlendirme ortamına yerleştirilir.
Scheme ve ML arasındaki bir diğer önemli fark, ML'nin bir
buyruk bir dilinkiyle bundan daha yakından ilgili olan sözdizimi
LISP'nin. Örneğin, aritmetik ifadeler makine öğreniminde infix kullanılarak yazılır.
notasyon.
ML'deki işlev bildirimleri genel biçimde görünür
fun function_name(resmi parametreler) = ifade;
Çağrıldığında, ifadenin değeri işlev tarafından döndürülür. Aslında,
ifade, noktalı virgül ve sur- ile ayrılmış ifadelerin bir listesi olabilir.
parantez içinde yuvarlanır. Bu durumda dönüş değeri, son ifadenin değeridir.
siyon. Tabii yan etkileri olmadıkça sondan önceki ifadeler
hiçbir amaca hizmet etme. Çünkü ML'nin sahip olduğu bölümleri düşünmüyoruz.
yan etkiler, sadece tek bir ifade ile fonksiyon tanımlarını dikkate alıyoruz.
Şimdi tür çıkarımını tartışabiliriz. Aşağıdaki ML işlevini göz önünde bulundurun
beyan:
eğlenceli çevre(r) = 3.14159 * r * r;
Adlı bu belirtir bir işlev circumf bir kayan nokta alır ( gerçek içinde
ML) bağımsız değişkeni ve bir kayan nokta sonucu üretir. Türler tahmin edilir
ifadedeki değişmezin türünden. Aynı şekilde fonksiyonda
eğlenceli zamanlar10(x) = 10 * x;
bağımsız değişken ve işlevsel değerin int türünde olduğu anlaşılır .
Aşağıdaki ML işlevini göz önünde bulundurun:
eğlenceli kare(x) = x * x;
ML, hem parametrenin türünü hem de
* fonksiyon tanımındaki operatör. Bu bir aritmetik operatör olduğundan,

Sayfa 724
15.7 ML 703
parametrenin tipi ve fonksiyonun sayısal olduğu varsayılır. ML'de,
varsayılan sayısal tür int'dir . Bu nedenle, parametrenin türünün
ve dönüş değeri meydanına olduğunu int .
Eğer kare olduğu gibi bir kayan nokta değeri ile çağrıldı
kare(2.75);
ML gerçek değerleri int türüne zorlamadığından bir hataya neden olur . Eğer
square'in gerçek parametreleri kabul etmesini istedik , şu şekilde yeniden yazılabilirdi:
eğlenceli kare(x) : gerçek = x * x;
ML aşırı yüklenmiş işlevlere izin vermediğinden, bu sürüm
önceki int sürümüyle birlikte bulunur. Tanımlanan son sürüm,
sadece bir.
Fonksiyonel değerin real olarak yazılması , şunu çıkarmak için yeterlidir.
parametre de gerçek tiptir. Aşağıdaki tanımların her biri aynı zamanda
yasal:
eğlenceli kare(x : gerçek ) = x * x;
eğlenceli kare(x) = (x : gerçek ) * x;
eğlenceli kare(x) = x * (x : gerçek );
Tür çıkarımı, Miranda, Haskell, işlevsel dillerinde de kullanılır.
ve F#.
ML seçim denetimi akış yapısı, buyruğunkine benzer.
Diller. Aşağıdaki genel forma sahiptir:
if ifade o zaman then_expression else else_expression
İlk ifade bir Boolean değeri olarak değerlendirilmelidir.
Scheme'in koşullu ifadeleri fonksiyon tanımında görünebilir.
ML'de nition seviyesi. Şemada, COND işlevi, durumu belirlemek için kullanılır.
tarafından döndürülen değeri belirten verilen parametrenin değeri
KOŞUL . ML'de, bir fonksiyon tarafından gerçekleştirilen hesaplama şu şekilde tanımlanabilir:
verilen parametrenin farklı biçimleri. Bu özelliğin taklit edilmesi amaçlanmıştır.
matematikte koşullu fonksiyon tanımlarının şekli ve anlamı. İçinde
ML, bir fonksiyonun dönüş değerini tanımlayan özel ifade
verilen parametreye göre desen eşleştirmesi ile seçilir. Örneğin,
bu model eşleştirmeyi kullanmadan, faktöriyel hesaplamak için bir fonksiyon
aşağıdaki gibi yazılmalıdır:
eğlenceli fact (n: int ): int = eğer n <= 1 sonra 1
başka n * gerçek(n − 1);
Parametre modeli kullanılarak bir fonksiyonun birden fazla tanımı yazılabilir
eşleştirme. Şekline bağlı olarak farklı fonksiyon tanımları

Sayfa 725
704
Bölüm 15 Fonksiyonel Programlama Dilleri
parametre bir VEYA simgesiyle ( | ) ayrılır . Örneğin, desen kullanarak
eşleştirme, faktöriyel fonksiyon aşağıdaki gibi yazılabilir:
eğlenceli gerçek(0) = 1
| gerçek(1) = 1
| gerçek(n : int ): int = n * gerçek(n − 1);
Eğer aslında gerçek parametre olarak adlandırılır 0 , ilk tanımı kullanılır; Eğer
gerçek parametre 1'dir, ikinci tanım kullanılır; bir int değeri ise
ne 0 ne de 1 gönderilmez, üçüncü tanım kullanılır.
Bölüm 6'da tartışıldığı gibi ML, listeleri ve liste işlemlerini destekler. Hatırlamak
hd , tl ve :: ML'nin Scheme'in CAR , CDR ve CONS sürümleridir .
Desenli fonksiyon parametrelerinin mevcudiyeti nedeniyle, hd ve tl
işlevler ML'de CAR ve CDR'den çok daha az kullanılır.
Şema. Örneğin, resmi bir parametrede, ifade
(h :: t)
aslında iki resmi parametredir, verilen liste parametresinin başı ve kuyruğu,
tek karşılık gelen gerçek parametre bir liste iken. Örneğin, sayı-
Belirli bir listedeki elemanların sayısı aşağıdaki fonksiyonla hesaplanabilir:
eğlence uzunluğu([]) = 0
| uzunluk(h :: t) = 1 + uzunluk(t);
Bu kavramların başka bir örneği olarak, ekleme işlevini düşünün ,
bu, Scheme ekleme işlevinin yaptığını yapar:
eğlenceli ekleme([], lis2) = lis2
| ekle(h :: t, lis2) = h :: ekle(t, lis2);
Bu fonksiyondaki ilk durum, çağrılan fonksiyonun durumunu ele alır.
ilk parametre olarak boş bir liste ile. Bu durum da yinelemeyi sonlandırır.
ilk çağrı boş olmayan bir ilk parametreye sahip olduğunda. ikinci vaka
işlev, ilk parametre listesini baş ve kuyruk ( hd ve tl ) olarak böler .
Kafa olup cons olarak kuyruk kullanan yinelemeli çağrı, sonucu üzerine ed
onun ilk parametresi.
ML'de adlar, aşağıdaki değer bildirim ifadeleriyle değerlere bağlıdır:
form
val yeni_adı = ifade ;
Örneğin,
val mesafe = zaman * hız;
Bu ifadenin tam olarak atama ifadeleri gibi olduğu fikrine kapılmayın.
emir kipi dillerinde, çünkü öyle değil. Val ifadesi bağlamalar a bir ad
değer, ancak ad daha sonra yeni bir değere geri döndürülemez. Eh, bir anlamda

Sayfa 726
15.7 ML 705
Yapabilmek. Aslında, bir adı ikinci bir val deyimiyle yeniden bağlarsanız , bir
önceki sürümle ilgili olmayan değerlendirme ortamına yeni giriş
adın sihri. Aslında yeni bağlamadan sonra eski değerlendirme ortamı
giriş (önceki bağlama için) artık görünmez. Ayrıca yeni tip
bağlamanın önceki bağlamayla aynı olması gerekmez. val ifadeleri
yan etkileri yoktur. Mevcut değerlendirmeye sadece bir isim eklerler
çevre ve bir değere bağlayın.
Val'in normal kullanımı bir let ifadesindedir. 10 Aşağıdakileri göz önünde bulundurun
örnek:
İzin Vermek
değer yarıçapı = 2.7
değer pi = 3.14159
içinde
pi * yarıçap * yarıçap
son ;
ML, işlevlerde yaygın olarak kullanılan birkaç üst düzey işlevi içerir.
ulusal programlama Bunlar arasında listeler için bir filtreleme işlevi, filtre ,
parametresi olarak bir yüklem işlevi alır. Yüklem işlevi genellikle
ML'de tam olarak bir fonksiyon gibi tanımlanan bir lambda ifadesi olarak verilir,
fn ayrılmış kelime hariç , fun yerine ve tabii ki lambda
ifade isimsizdir. filter parametre olarak bir liste alan bir işlev döndürür.
eter. Listenin her bir öğesini yüklemle test eder. Üzerinde bulunduğu her bir eleman
yüklem true döndürür, yeni bir listeye eklenir; bu,
işlev. Aşağıdaki filtre kullanımını göz önünde bulundurun :
filtre( fn (x) => x < 100, [25, 1, 50, 711, 100, 150, 27,
161, 3]);
Bu uygulama [25, 1, 50, 27, 3] döndürür .
Harita işlevi bir işlev olan tek bir parametre alır. Sonuç-
ing işlevi parametre olarak bir liste alır. İşlevini her öğeye uygular
ve bu uygulamaların sonuçlarının bir listesini döndürür. Yi hesaba kat
aşağıdaki kod:
eğlence küpü x = x * x * x;
val cubeList = harita küpü;
val newList = cubeList [1, 3, 5];
Yürütmeden sonra, newList'in değeri [1, 27, 125] olur . Bu yapılabilir
daha basit olarak, küp işlevini aşağıdaki gibi bir lambda ifadesi olarak tanımlayarak
Takip etmek:
val newList = harita ( fn x => x * x * x, [1, 3, 5]);
10. Let ifadeleri Bölüm 5'te tanıtıldı.

Sayfa 727
706
Bölüm 15 Fonksiyonel Programlama Dilleri
ML, iki işlevi oluşturmak için bir ikili operatöre sahiptir, o (küçük harf
"Ey"). Örneğin, önce f fonksiyonunu uygulayan bir h fonksiyonu oluşturmak ve sonra
g işlevini f öğesinden döndürülen değere uygular , aşağıdakileri kullanabiliriz:
val h = gof;
Açıkça söylemek gerekirse, ML işlevleri tek bir parametre alır. ne zaman bir işlev-
birden fazla parametre ile tanımlanmışsa, ML parametreleri dikkate alır.
normalde bir tanımlama grubu değerini sınırlayan parantezler olsa bile bir tanımlama grubu olmak
isteğe bağlıdır. Parametreleri (tuple elemanları) ayıran virgüller
gereklidir.
Körleme işlemi, bir işlevi birden fazla parametreyle değiştirir
diğerini alan bir işlevi döndüren bir parametreli bir işlevle
başlangıç ​​fonksiyonunun parametreleri.
Birden fazla parametre alan ML fonksiyonları curried'de tanımlanabilir.
parametreler (ve sınırlayıcı işaretler) arasındaki virgülleri dışarıda bırakarak oluşturun.
parantez). 11 Örneğin, aşağıdakilere sahip olabiliriz:
eğlenceli ekleme ab = a + b;
Bu, iki parametreli bir işlevi tanımlıyor gibi görünse de, aslında
birini sadece bir parametre ile tanımlar. Eklenti işlevi bir tamsayı ParamChannel alır
eter ( a ) ve bir tamsayı parametresi ( b ) alan bir işlev döndürür . Bir arama
bu işleve, aşağıdaki gibi parametreler arasındaki virgülleri de hariç tutar.
Takip etmek:
3 5 ekleyin;
Bu ekleme çağrısı , beklendiği gibi 8 değerini döndürür .
Curried fonksiyonlar ilginç ve kullanışlıdır çünkü yeni fonksiyonlar
kısmi değerlendirme ile onlardan inşa edilmiştir. Kısmi değerlendirme şu anlama gelir:
işlev, en soldaki bir veya daha fazla parametre için gerçek parametrelerle değerlendirilir.
resmi parametreler. Örneğin, aşağıdaki gibi yeni bir fonksiyon tanımlayabiliriz:
eğlenceli ekle5 x = 5 x ekle;
Add5 fonksiyonu gerçek parametre alır 5 ve değerlendirir ekleme işlevini
ilk resmi parametresinin değeri olarak 5 ile . 5 ekleyen bir işlev döndürür
aşağıdaki gibi tek parametresine:
değer sayısı = add5 10;
Değeri num artık 15 . Herhangi bir sayıda yeni işlev oluşturabiliriz
Belirli bir parametreye belirli bir sayı eklemek için curried işlevinden ekleyin .
11. Bu fonksiyon biçimi, onları inceleyen İngiliz matematikçi Haskell Curry'nin adını almıştır.

Sayfa 728
15.8 Haskell 707
Curried fonksiyonlar ayrıca Scheme, Haskell ve F# ile de yazılabilir. bağla-
aşağıdaki Şema işlevinden yararlanın:
(TANIMLA (xy ekle) (+ xy))
Bunun curried versiyonu aşağıdaki gibi olacaktır:
(TANIMLA (y ekle) (LAMBDA (x) (+ yx)))
Bu şu şekilde çağrılabilir:
((3 ekleyin) 4)
ML, numaralandırılmış türlere, dizilere ve demetlere sahiptir. ML'de ayrıca istisna han-
dling ve soyut veri türlerini uygulamak için bir modül tesisi.
ML, programlama dilinin evrimi üzerinde önemli bir etkiye sahiptir.
göstergeler. Dil araştırmacıları için en çok çalışılan alanlardan biri haline gelmiştir.
göstergeler. Ayrıca, aralarında birkaç müteakip dil ​​üretti.
Haskell, Caml, OCaml ve F#.
15.8 Haskell
Haskell (Thompson, 1999), benzer bir sözdizimi kullanması bakımından ML'ye benzerdir.
statik kapsamlı, kesin olarak yazılmıştır ve aynı tür çıkarım yöntemini kullanır.
Haskell'i ML'den ayıran üç özelliği vardır: Birincisi, işlev-
Haskell'deki işlevler aşırı yüklenebilir (ML'deki işlevler olamaz). İkincisi, katı olmayan
semantik Haskell'de kullanılırken, ML'de (ve diğer birçok programlama
diller) katı anlambilim kullanılır. Üçüncüsü, Haskell saf bir işlevsel pro-
dilbilgisi dili, yani yanları olan hiçbir ifade veya ifadeye sahip değildir.
etkiler, oysa ML bazı yan etkilere izin verir (örneğin, ML değiştirilebilir
diziler). Hem katı olmayan semantik hem de fonksiyon aşırı yüklemesi daha da farklıdır.
bu bölümde daha sonra tartışıldı.
Bu bölümdeki kod Haskell'in 1.4 versiyonunda yazılmıştır.
Aşağıdaki faktöriyel fonksiyonun tanımını göz önünde bulundurun.
parametrelerinde eşleme:
gerçek 0 = 1
gerçek 1 = 1
gerçek n = n * gerçek (n – 1)
Bu tanım ile ML sürümü arasındaki sözdizimindeki farklılıkları not edin.
Bölüm 15.7. İlk olarak, fonksiyon tanımını tanıtmak için ayrılmış bir kelime yoktur.
(ML'de eğlence ). İkincisi, alternatif fonksiyon tanımları (farklı
resmi parametreler) hepsi aynı görünüme sahiptir.

Sayfa 729
708
Bölüm 15 Fonksiyonel Programlama Dilleri
Desen eşleştirme kullanarak, bilgisayar için bir fonksiyon tanımlayabilir n th
Aşağıdakileri içeren Fibonacci sayısı:
fib 0 = 1
fib 1 = 1
fib (n + 2) = fib (n + 1) + fib n
Çevreyi belirtmek için bir fonksiyon tanımının satırlarına korumalar eklenebilir.
tanımın uygulanabileceği durumlar. Örneğin,
gerçek n
| n == 0 = 1
| n == 1 = 1
| n > 1 = n * gerçek(n − 1)
Faktöriyelin bu tanımı öncekinden daha kesindir, çünkü
gerçek parametre değerlerinin, çalıştığı değerlere göre aralığı. Bu form
Bir fonksiyon tanımının matematiksel ifadesinden sonra koşullu ifade olarak adlandırılır.
dayandığı ifadelerdir.
Bir başka şekilde , bir koşullu ifadede geçen koşulu olarak görünebilir
bariz semantik ile. Örneğin,
alt n
| n < 10
= 0
| n > 100 = 2
| aksi halde = 1
Buradaki gardiyanlar ile korunan komutlar arasındaki benzerliğe dikkat edin.
Bölüm 8'de tartışılmıştır.
Amacı aşağıdakiyle aynı olan aşağıdaki işlev tanımını göz önünde bulundurun:
Bölüm 15.7'deki ilgili ML işlevi:
kare x = x * x
Ancak bu durumda, Haskell'in polimorfizmi desteklemesi nedeniyle, bu işlev
tion herhangi bir sayısal türde bir parametre alabilir.
ML'de olduğu gibi, listeler Haskell'de parantez içinde yazılır.
renkler = ["mavi", "yeşil", "kırmızı", "sarı"]
Haskell, bir liste operatörleri koleksiyonu içerir. Örneğin, listeler şunlar olabilir:
ile catenated ++ , : bir infix versiyonu olarak hizmet vermektedir İNŞAAT ve .. belirtmek için kullanılır
bir listedeki aritmetik dizi. Örneğin,
5:[2, 7, 9] sonucu [5, 2, 7, 9]
[1, 3..11] sonucu [1, 3, 5, 7, 9, 11]
[1, 3, 5] ++ [2, 4, 6] ile sonuçlanır [1, 3, 5, 2, 4, 6]

Sayfa 730
15.8 Haskell 709
: operatörünün ML'nin :: operatörü gibi olduğuna dikkat edin . 12 Kullanımı : ve desen
eşleştirme, verilen bir ürünün çarpımını hesaplamak için basit bir fonksiyon tanımlayabiliriz.
numara listesi:
ürün [] = 1
çarpım (a:x) = a * çarpım x
product kullanarak , daha basit formda bir faktöriyel fonksiyon yazabiliriz.
olgu n = ürün [1..n]
Haskell, makine öğreniminin let ve val'sine benzer bir let yapısı içerir . İçin
mesela yazabiliriz
kuadratic_root abc =
İzin Vermek
minus_b_over_2a = - b / (2.0 * a)
root_part_over_2a =
sqrt(b ^ 2 − 4.0 * a * c) / (2.0 * a)
içinde
minus_b_over_2a − root_part_over_2a,
minus_b_over_2a + root_part_over_2a
Haskell'in liste kavrayışları Bölüm 6'da tanıtıldı. Örneğin,
aşağıdakileri göz önünde bulundur:
[n * n * n | n <− [1..50]]
Bu, 1'den 50'ye kadar olan sayıların küplerinin bir listesini tanımlar. "Bir liste" olarak okunur.
tüm n*n*n'den öyle ki n , 1 ila 50 aralığından alınır.” Bu durumda,
niteleyici bir jeneratör şeklindedir . Bu numara oluşturur 1 için 50 .
Diğer durumlarda, niteleyiciler Boolean ifadeleri biçimindedir;
durumda bunlara testler denir . Bu gösterim algoritmaları tanımlamak için kullanılabilir
listelerin permütasyonlarını bulmak ve listeleri sıralamak gibi birçok şey yapmak için.
Örneğin, n sayısı verildiğinde aşağıdaki işlevi göz önünde bulundurun:
tüm faktörlerinin bir listesini döndürür:
çarpanlar n = [ ben | ben <− [1..n ` div ` 2], n ` mod ` ben == 0]
Faktörlerdeki liste kavrayışı , her biri geçici olarak bir sayı listesi oluşturur.
adı bağlanmış i arasında değişen, 1 için N / 2 , öyle ki, n ' mod ` i sıfırdır. Bu
gerçekten de belirli bir sayının çarpanlarının çok titiz ve kısa bir tanımıdır.
Çevre backticks (geri kesme işareti) div ve mod için kullanılır
12. ML'nin bir isme bir tür adı eklemek için : ve CONS için : : kullanması ilginçtir.
Haskell bu iki operatörü tam tersi şekilde kullanır.

Sayfa 731
710
Bölüm 15 Fonksiyonel Programlama Dilleri
bu işlevlerin infix kullanımını belirtin. İşlevsel olarak çağrıldıklarında
gösterimde, div n 2'de olduğu gibi , geri tepmeler kullanılmaz.
Ardından, aşağıdaki uygulamada gösterilen Haskell'in kesinliğini düşünün.
hızlı sıralama algoritmasının açıklaması:
sırala [] = []
sırala (h:t) = sırala [b | b <− t, b <− h]
++ [s] ++
sırala [b | b <− t, b > h]
Bu programda, liste başlığına eşit veya daha küçük olan liste öğeleri kümesi
baş öğesiyle sıralanır ve sıralanır, ardından
liste başlığından daha büyükse sıralanır ve önceki sonuca göre sıralanır.
Bu hızlı sıralama tanımı, aynı tanımdan önemli ölçüde daha kısa ve basittir.
zorunlu bir dilde kodlanmış algoritma.
Bir programlama dili, tüm gerçek parametrelerin olmasını gerektiriyorsa katıdır .
tam olarak değerlendirilir, bu da bir fonksiyonun değerinin aşağıdakilere bağlı olmamasını sağlar.
parametrelerin değerlendirildiği sıra. Eğer bir dil katı değildir
katı bir gerekliliği yoktur. Katı olmayan dillerin birkaç tane olabilir.
katı dillere göre belirgin avantajlar. Birincisi, katı olmayan diller geneldir.
daha verimlidir, çünkü bazı değerlendirmelerden kaçınılır. 13 İkincisi, bazı inter-
mümkün olmayan katı olmayan dillerle tahmin yetenekleri mümkündür
katı dillerle. Bunların arasında sonsuz listeler var. Kesin olmayan diller
tembel değerlendirme adı verilen bir değerlendirme formu kullanın ; bu, ifadelerin
yalnızca değerlerine ihtiyaç duyulduğunda ve gerektiğinde değerlendirilir.
Şemada bir fonksiyonun parametrelerinin tamamen değerlendirildiğini hatırlayın.
işlev çağrılmadan önce, bu nedenle katı anlambilimine sahiptir. Tembel değerlendirme
gerçek bir parametrenin yalnızca değeri değerlendirmek için gerekli olduğunda değerlendirilir.
işlev. Bu nedenle, bir işlevin iki parametresi varsa, ancak belirli bir yürütmede
fonksiyonun ilk parametresi kullanılmaz, gerçek parametre için iletilir
bu uygulama değerlendirilmeyecektir. Ayrıca, eğer gerçek bir projenin sadece bir parçasıysa
fonksiyonun yürütülmesi için parametrenin değerlendirilmesi gerekir, gerisi bırakılır
değerlendirilmemiş. Son olarak, gerçek parametreler yalnızca bir kez değerlendirilir.
aynı gerçek parametre bir işlev çağrısında birden fazla görünür.
Daha önce belirtildiği gibi tembel değerlendirme, sonsuz veri yapısını tanımlamaya izin verir.
türler. Örneğin, aşağıdakileri göz önünde bulundurun:
pozitifler = [0..]
çiftler = [2, 4..]
kareler = [n * n | n <− [0..]]
Tabii ki, hiçbir bilgisayar bu listelerin tüm sayılarını temsil edemez.
ancak tembel değerlendirme kullanılıyorsa bu kullanımlarını engellemez. Örneğin, eğer
13. Bunun Boolean ifadelerinin kısa devre değerlendirmesiyle nasıl ilişkili olduğuna dikkat edin.
bazı zorunlu dillerde.

Sayfa 732
15.8 Haskell 711
belirli bir sayının tam kare olup olmadığını bilmek istedik,
üyelik fonksiyonu ile kareler listesi. Bir yüklem fonksiyonumuz olduğunu varsayalım.
Belirli bir atomun belirli bir listeyi içerip içermediğini belirleyen adlandırılmış üye .
O zaman olduğu gibi kullanabiliriz
üye 16 kare
hangi True döndürürdü . Kareler tanımı kadar değerlendirilecektir
16 bulunmuştur. Üye işlev dikkatli yazılması gerekir.
Spesifik olarak, aşağıdaki gibi tanımlandığını varsayalım:
üye b [] = Yanlış
üye b (a:x)= (a == b) || üye bx
Bu tanımın ikinci satırı, ilk parametreyi başına böler ve
kuyruk. Dönüş değeri, başlıktan herhangi biri için geçerli olan öğeyle eşleşirse doğrudur.
( b ) arıyor veya listenin sonundaki özyinelemeli çağrı True döndürüyorsa .
Bu üye tanımı, yalnızca aşağıdaki durumlarda karelerle doğru şekilde çalışır:
verilen sayı bir tam kare idi. Değilse, kareler üretmeye devam ederdi
sonsuza kadar veya bazı bellek sınırlamalarına ulaşılana kadar,
Listede verilen numara. Aşağıdaki fonksiyon üyelik testini gerçekleştirir
sıralı bir listenin, aramayı bırakma ve bir sayı ise False döndürme
aranan sayıdan daha büyük bulundu. 14
üye2 n (m:x)
| m < n = üye2 nx
| m == n = Doğru
| aksi halde = Yanlış
Tembel değerlendirme bazen bir modülerleştirme aracı sağlar. Farz et ki
Bir program içinde işlev çağrısı olduğu f ve parametre f dönüş
bir fonksiyonun değeri g . 15 Yani, elimizde f(g(x)) var . Ayrıca g'nin ürettiğini varsayalım
her seferinde az miktarda büyük miktarda veri ve bu f bu verileri işlemelidir,
Her seferinde biraz. Geleneksel zorunluluk dilinde gr üzerinde aday olacağını
çıktısının bir dosyasını üreten tüm girdi. Ardından f , dosyayı şu şekilde kullanarak çalışır:
onun girişi. Bu yaklaşım, dosyayı hem yazmak hem de okumak için zaman gerektirir, çünkü
dosya için depolama yanı sıra. Tembel değerlendirme ile f ve g uygulamaları
örtük olarak sıkı bir şekilde senkronize olacaktır. g işlevi yalnızca uzun süre yürütülür
f'nin işlemeye başlaması için yeterli veriyi üretmeye yetecek kadar . Ne zaman f hazır
daha fazla veri için, f beklerken daha fazla üretmek üzere g yeniden başlatılacaktır . Eğer f termi-
g'nin tüm çıktısını almadan nates , g iptal edilir, böylece yararsız olmaktan kaçınılır
hesaplama. Ayrıca, g'nin bir sonlandırma işlevi olması gerekmez, çünkü belki de
sonsuz miktarda çıktı üretir. g f olduğunda sonlandırmaya zorlanacak
14. Bu, listenin artan sırada olduğunu varsayar.
15. Bu örnek Hughes'da (1989) görülmektedir.

Sayfa 733
712
Bölüm 15 Fonksiyonel Programlama Dilleri
sona erer. Bu nedenle, tembel değerlendirme altında g , mümkün olduğunca az çalışır. Bu değerlendirme-
tion süreci, programların üreteç birimlerine modülerleştirilmesini destekler ve
jeneratörün çok sayıda olası sonuç ürettiği seçici birimler
ve seçici uygun alt kümeyi seçer.
Tembel değerlendirme maliyetleri olmadan değildir. Eğer kesinlikle şaşırtıcı olurdu
bu tür ifade gücü ve esneklik özgürdü. Bu durumda maliyet çok
çok daha yavaş yürütme hızı ile sonuçlanan daha karmaşık anlambilim.
15.9 F#
F#, çekirdeği temel alınan bir .NET işlevsel programlama dilidir.
ML ve Haskell'in soyundan gelen OCaml. Her ne kadar temel-
zihinsel olarak işlevsel bir dil, zorunlu özellikleri ve destekleri içerir.
nesne yönelimli programlama. en önemli özelliklerinden biri
F#, kapsamlı bir yardımcı program kitaplığı olan tam özellikli bir IDE'ye sahip olmasıdır.
zorunlu, nesne yönelimli ve işlevsel programlamayı destekler ve
işlevsel olmayan diller koleksiyonuyla birlikte çalışabilirlik (tüm .NET
Diller).
F# birinci sınıf bir .NET dilidir. Bu, F# programlarının etkileşime girebileceği anlamına gelir.
diğer .NET dilleriyle her şekilde. Örneğin, F# sınıfları kullanılabilir
ve diğer dillerdeki programlar tarafından alt sınıflara ayrılır ve bunun tersi de geçerlidir. Üstelik,
F# programlarının tüm .NET Framework API'lerine erişimi vardır. F# uygulaması
açıklama Microsoft'tan ücretsiz olarak edinilebilir ( http://research.microsoft
.com/fsharp/fsharp.aspx) . Ayrıca Visual Studio tarafından da desteklenmektedir.
F#, çeşitli veri türleri içerir. Bunlar arasında tuple'lar var, bunlar gibi
Python ve işlevsel diller ML ve Haskell, listeler, ayrımcılığa uğradı
sendikalar, ML birleşimlerinin genişlemesi ve ML'deki gibi kayıtlar
bileşenlerin adlandırılması dışında demetler gibidir. F# hem değişken hem de
değişmez diziler
Bölüm 6'dan, F# listelerinin makine öğrenimi listelerine benzer olduğunu hatırlayın:
elemanların noktalı virgülle ayrıldığı ve hd ve tl çağrılması gerektiği
Liste yöntemleri olarak .
F#, .NET ad alanından türler olan sıra değerlerini destekler
System.Collections.Generic.IEnumerable . F#'da diziler
seq<type> olarak kısaltılır , burada <type> jenerik türünü belirtir.
Örneğin, seq<int> türü bir tamsayı değerleri dizisidir. Sıra
değerler üreteçlerle oluşturulabilir ve yinelenebilir. En basit
diziler, aşağıdaki örnekte olduğu gibi aralık ifadeleriyle oluşturulur:
izin X = seq {1..4} ;;
F# örneklerinde, etkileşimli yorumlayıcının kullanıldığını varsayıyoruz.
her ifadenin sonunda iki noktalı virgül gerektirir. Bu ifade
oluşturur seq [1; 2; 3; 4] . (Liste ve sıra öğeleri şu şekilde ayrılır:
noktalı virgül.) Bir dizinin üretimi tembeldir; örneğin, aşağıdakiler

Sayfa 734
15.9 F# 713
tanımlar y çok uzun bir sekansı olduğu, ancak gerekli elemanlar üretimi genelde olan
yedik. Görüntülemek için yalnızca ilk dördü oluşturulur.
izin y seq {0..100000000} = ;;
y;;
val it: sıra<int> = sıra[0; 1; 2; 3;. . .]
Tanımlar yukarıdaki ilk satır y ; ikinci satır, y değerinin olmasını ister
görüntülenen; üçüncüsü, F# etkileşimli yorumlayıcısının çıktısıdır.
Tamsayı dizi tanımları için varsayılan adım boyutu 1'dir , ancak
aşağıdaki gibi, aralık belirtiminin ortasına dahil ederek ayarlayın
örnek:
sıra {1..2..7};;
Bu seq [1; 3; 5; 7] .
Bir dizinin değerleri, aşağıdaki gibi bir for - in yapısı ile yinelenebilir :
aşağıdaki örnek:
izin SEQ1 = seq {0..3..11} ;;
için bir değer olarak SEQ1 do "değeri =% D" değeri ;; printfn
Bu, aşağıdakileri üretir:
değer = 0
değer = 3
değer = 6
değer = 9
Yineleyiciler, aşağıdaki örnekte olduğu gibi diziler oluşturmak için de kullanılabilir:
let küpler = seq { for i in 1.5 −> (i, i * i * i)};;
Bu, aşağıdaki demet listesini oluşturur:
sıra [(1, 1); (2, 8); (3, 27); (4, 64); (5, 125)]
Koleksiyon oluşturmak için yineleyicilerin bu kullanımı, bir liste anlama biçimidir.
Sıralama, listeler ve diziler oluşturmak için de kullanılabilir, ancak bunlarda
durumda, nesil tembel değildir. Aslında, listeler arasındaki temel fark
ve F#'daki diziler, dizilerin tembel olduğu ve dolayısıyla sonsuz olabileceğidir, oysa
listeler tembel değildir. Listeler bütünüyle bellekte saklanır. bu değil
sekanslarla ilgili durum.
F#'ın işlevleri, ML ve Haskell'in işlevlerine benzer. Adlandırılırsa, onlar
let ifadeleri ile tanımlanır . İsimsiz ise, yani teknik olarak

Sayfa 735
714
Bölüm 15 Fonksiyonel Programlama Dilleri
lambda ifadeleri, eğlenceye ayrılmış kelime ile tanımlanırlar . Takip-
lambda ifadesi onların sözdizimini gösterir:
( eğlenceli ab -> a / b)
let ve a ile tanımlanan bir ad arasında hiçbir fark olmadığını unutmayın.
let ile tanımlanan parametreler olmadan işlev .
Girinti, bir fonksiyon tanımının kapsamını göstermek için kullanılır. Örneğin,
aşağıdaki fonksiyon tanımını göz önünde bulundurun:
let = f
let pi 3.14159 =
iki Pi = 2.0 * pi olsun
ikiPi;;
ML gibi F#'ın sayısal değerleri zorlamadığını unutmayın, bu nedenle bu işlev
2.0 yerine ikinci son satırda 2 kullanılırsa bir hata bildirilir.
Bir işlev özyinelemeliyse, ayrılmış sözcük rec , adından önce gelmelidir.
onun tanımı. Aşağıdaki faktöriyelin bir F# versiyonudur:
faktöriyel x = ver
Eğer x <1 daha sonra 1
başka n * faktöriyel(n − 1)
İşlevlerde tanımlanan adlar kapsam dışı tutulabilir, yani bunlar olabilir
eski kapsamını sona erdiren yeniden tanımlanmıştır. Örneğin, sahip olabiliriz
Takip etmek:
izin x4, x =
let x = x * x
let x = x * x
x;;
Bu işlevde, x4 işlevinin gövdesindeki ilk izin yeni bir sürüm oluşturur.
bir yon x tanımlayarak, parametre karesinin değerine sahip olması , x . Bu
parametrenin kapsamını sonlandırır. Yani, fonksiyon gövdesindeki ikinci izin
Yeni kullanır x onun sağ tarafında ve henüz başka bir versiyonunu oluşturur x suretle,
önceki let'te oluşturulan x'in kapsamını sonlandırmak .
F#'da iki önemli işlevsel operatör vardır, ardışık düzen ( |> ) ve
fonksiyon bileşimi ( >> ). Boru hattı operatörü, ikili bir operatördür.
bir ifade olan sol işleneninin değerini son parametreye gönderir
doğru işlenen olan işlev çağrısının. Birlikte zincirlemek için kullanılır
Her çağrıya işlenmekte olan veriler akıtılırken işlev çağrıları. Yi hesaba kat
yüksek dereceli işlevler filtresini ve haritasını kullanan aşağıdaki örnek kod :
izin myNums = [1; 2; 3; 4; 5]
olsun bilesTimesFive = myNums

Sayfa 736
15.10 Temel Zorunlu Dillerde İşlevsel Programlama Desteği 715
|> Liste.filtre ( eğlence n −> n % 2 = 0)
|> List.map ( eğlence n -> 5 * n)
EvensTimesFive fonksiyon listesi ile başlar myNums filtreler,
filter ile bile olmayan ve bir lambda ifadesini eşlemek için map kullanan sayılar
Belirli bir listedeki sayıları beşle çarpan sion. dönüş değeri
evensTimesFive olduğu [10; 20] .
İşlev oluşturma operatörü, sol tarafını uygulayan bir işlev oluşturur.
bir işlev olan belirli bir parametreye işlenen ve ardından sonucu iletir
bu işlevden, aynı zamanda bir işlev olan sağ işlenenine döndürülür. Böyle,
F# ifadesi (f >> g) x , matematiksel ifadeye eşdeğerdir
g(f(x)) .
ML gibi, F# curried işlevleri ve kısmi değerlendirmeyi destekler. makine öğrenimi
Bölüm 15.7'deki örnek F# ile aşağıdaki gibi yazılabilir:
let eklemek ab = a + b ;;
let add5 = 5 ekleyin ;;
ML'den farklı olarak, F#'daki resmi parametre listesinin sözdiziminin aynı olduğuna dikkat edin.
tüm işlevler için, böylece birden fazla parametreli tüm işlevler birleştirilebilir.
F# birkaç nedenden dolayı ilginçtir: Birincisi, geçmişteki işlevsellik üzerine kuruludur.
işlevsel bir dil olarak diller. İkincisi, neredeyse tüm programları destekler-
Günümüzde yaygın olarak kullanılan ming metodolojileri. Üçüncüsü, ilk işlevsel
yaygın olarak kullanılan diğer dillerle birlikte çalışabilirlik için tasarlanmış bir dildir.
Dördüncüsü, ayrıntılı ve iyi geliştirilmiş bir IDE ve
.NET ve çerçevesi ile yardımcı yazılım.
15.10 Primaril içinde Fonksiyonel Programlama desteği y
Zorunlu Diller
Zorunlu programlama dilleri her zaman yalnızca sınırlı destek sağlamıştır.
fonksiyonel programlama için Bu sınırlı destek, çok az kullanımla sonuçlandı.
fonksiyonel programlama için bu diller. En önemli kısıtlama,
İşlevsel programlamayla ilgili, geçmişin zorunlu dillerinden
üst düzey işlevler için destek eksikliği.
Fonksiyonel programa artan ilginin ve kullanımının bir göstergesi-
ming, onun için son on yılda ortaya çıkmaya başlayan kısmi destektir.
öncelikle zorunlu olan programlama dilleri. Örneğin, anonim
lambda ifadelerine benzeyen işlevler artık JavaScript, Python,
Ruby ve C#.
JavaScript'te, adlandırılmış işlevler aşağıdaki sözdizimi ile tanımlanır:
işlev adı ( biçimsel parametreler ) {
gövde
}

Sayfa 737
716
Bölüm 15 Fonksiyonel Programlama Dilleri
JavaScript'te aynı sözdizimi ile anonim bir işlev tanımlanmıştır, ancak aşağıdakiler hariçtir:
fonksiyonun adının atlandığını.
C#, sözdiziminden farklı bir sözdizimine sahip lambda ifadelerini destekler.
C# işlevleri. Örneğin, aşağıdakilere sahip olabiliriz:
ben => (i % 2) == 0
Bu lambda ifadesi,
verilen parametre ( i ) çift ( doğru ) veya tek ( yanlış ). C#'ın lambda ifadeleri
birden fazla parametreye ve birden fazla deyime sahip olabilir.
Python'un lambda ifadeleri, basit bir ifadeyi anonim olarak tanımlar
Birden fazla parametreye sahip olabilen fonksiyonlar. Bir lambda sözdizimi
Python'daki ifade aşağıdakilerle örneklenir:
lambda a, b : 2 * a – b
Biçimsel parametrelerin işlev gövdesinden iki nokta üst üste ile ayrıldığına dikkat edin.
Python, üst düzey işlevler filtresini ve haritayı içerir . ikisi de sık sık
lambda ifadelerini ilk parametre olarak kullanın. Bunların ikinci parametresi
bir dizi türüdür ve her ikisi de ikincileriyle aynı dizi türünü döndürür
parametre. Python'da diziler, listeler ve demetler diziler olarak kabul edilir. bağla-
Python'da harita işlevini kullanmanın aşağıdaki örneğini inceleyin:
harita( lambda x: x ** 3, [2, 4, 6, 8])
Bu çağrı [8, 64, 216, 52] döndürür .
Python ayrıca kısmi işlev uygulamalarını da destekler. Aşağıdakileri göz önünde bulundur
örnek:
dan operatör ithalat eklenti
add5 = kısmi (ekle, 5)
Buradaki from bildirimi, ekleme işleminin işlevsel sürümünü içe aktarır.
adlı entegratör, eklenti gelen operatör modülü.
add5 tanımlandıktan sonra , aşağıdaki gibi bir parametre ile kullanılabilir:
ekle5(15)
Bu çağrı 20 döndürür .
Bölüm 6'da açıklandığı gibi, Python listeleri ve liste anlamalarını içerir.
Ruby'nin blokları, yöntemlere gönderilen etkin bir şekilde alt programlardır.
bu da yöntemi daha yüksek dereceli bir alt program yapar. Bir Ruby bloğu olabilir
lambda ile bir alt program nesnesine dönüştürülür . Örneğin, şunu düşünün:
Takip etmek:
çarpı = lambda {|a, b| bir * b}

Sayfa 738
15.11 İşlevsel ve Zorunlu Dillerin Karşılaştırılması 717
Aşağıda, time kullanımına bir örnek verilmiştir :
x = kez.(3, 4)
Bu setler x için 12 . Zaman nesne aşağıdaki ile curried edilebilir:
kez5 = kez.curry.(5)
Bu fonksiyon aşağıdaki gibi kullanılabilir:
x5 = çarpı5.(3)
Bu ayarlar x5 için 15 .
C# , liste sınıfının FindAll yöntemini içerir . FindAll benzer
ML'nin filtre işlevi amacıyla . C# ayrıca genel bir liste verilerini de destekler
tip.
15.11 İşlevsel ve Zorunlu Dillerin Karşılaştırılması
Bu bölümde zorunlu ve işlev arasındaki bazı farklar tartışılmaktadır.
ulusal diller.
İşlevsel diller çok basit bir sözdizimsel yapıya sahip olabilir. Liste
LISP'in hem kod hem de veri için kullanılan yapısı bunu açıkça göstermektedir.
Zorunlu dillerin sözdizimi çok daha karmaşıktır. Bu yapar
öğrenmeleri ve kullanmaları daha zordur.
İşlevsel dillerin semantiği, aynı zamanda, işlevsel dillerinkinden daha basittir.
zorunlu diller. Örneğin, düz anlamsal anlambilim açıklamasında
Bölüm 3.5.2'de verilen zorunlu bir döngü yapısının, döngü dönüştürülür
yinelemeli bir yapıdan özyinelemeli bir yapıya. Bu dönüşüm gereksiz
sary, yinelemenin olmadığı saf bir işlevsel dilde. Üstelik,
tüm düz anlamlarda ifade yan etkisi olmadığını varsaydık.
Bölüm 3'teki buyruk yapıların anlamsal açıklamaları. Bu kısıtlama,
gerçekçi değil, çünkü tüm C tabanlı diller ifade yan etkileri içeriyor.
Bu kısıtlama, saf işlevlerin düz anlam tanımları için gerekli değildir.
ulusal diller.
İşlevsel programlama topluluğundaki bazı kişiler,
fonksiyonel programlamanın kullanılması, büyüklük sırasına göre bir artışla sonuçlanır.
üretkenlik, büyük ölçüde yalnızca 10 olduğu iddia edilen işlevsel programlardan dolayı
zorunlu karşılıkları kadar büyük yüzde. Bu tür sayılar varken
aslında belirli sorunlu alanlar için gösterilmiştir, diğer sorunlu alanlar için, işlevler
ulusal programlar, zorunlu çözümler kadar yüzde 25 daha büyüktür.
aynı problemler (Wadler, 1998). Bu faktörler, işlevsellik savunucularına izin verir.
zorunlu programlamaya göre üretkenlik avantajları talep etmek için programlama
4 ila 10 kez. Ancak, program boyutu tek başına mutlaka iyi bir ölçü değildir.
üretkenlik. Kesinlikle tüm kaynak kod satırları eşit karmaşıklığa sahip değildir,

Sayfa 739
718
Bölüm 15 Fonksiyonel Programlama Dilleri
ne de üretmek için aynı miktarda zaman alırlar. Aslında, nedeniyle
değişkenlerle uğraşmanın gerekliliği, zorunlu programların pek çok önemsiz
değişkenlerde küçük değişiklikler başlatmak ve yapmak için basit satırlar.
Yürütme verimliliği, karşılaştırma için başka bir temeldir. İşlevsel olduğunda
programlar yorumlanırsa, elbette kendi bilgisayarlarından çok daha yavaştırlar.
kazıklı zorunlu meslektaşları. Ancak, artık çoğu için derleyiciler var.
işlevsel diller, böylece yürütme, işlevsellik arasındaki eşitsizlikleri hızlandırır.
diller ve derlenmiş zorunlu diller artık o kadar iyi değil. Bir
Bunu söylemek cazip gelebilir çünkü işlevsel programlar önemli ölçüde
eşdeğer zorunlu programlardan daha küçük, çok fazla yürütmeleri gerekir
zorunlu programlardan daha hızlı. Ancak, çoğu zaman durum böyle değildir,
işlevsel alanın dil özelliklerinin bir koleksiyonu nedeniyle
Tembel değerlendirme gibi yürütme üzerinde olumsuz etkisi olan göstergeler
yeterlik. İşlevsel ve zorunlu kavramların göreceli etkinliğini göz önünde bulundurarak
programlar, ortalama bir işlevsel programın olduğunu tahmin etmek mantıklıdır.
zorunlu karşılığı (Wadler,
1998). Bu, kulağa genellikle önemli bir fark gibi gelebilir.
biri belirli bir uygulama için işlevsel dilleri reddetmek için. Ancak,
bu iki faktör farkı, yalnızca
hızı çok önemlidir. bir çok durum vardır
yürütme hızında iki faktörü önemli sayılmaz. Örneğin,
gibi zorunlu dillerde yazılmış birçok programın olduğunu düşünün.
JavaScript ve PHP ile yazılmış web yazılımları yorumlanır ve bu nedenle
eşdeğer derlenmiş sürümlerden çok daha yavaştır. Bu uygulamalar için,
yürütme hızı birinci öncelik değildir.
İşlevler arasındaki yürütme verimliliği farkının bir başka kaynağı
ve zorunlu programlar, zorunlu dillerin tasarlanmış olduğu gerçeğidir.
tasarım yaparken von Neumann mimarisi bilgisayarlarında verimli bir şekilde çalışmak için
fonksiyonel dillerin temeli matematiksel fonksiyonlara dayanmaktadır. Bu
zorunlu diller büyük bir avantaj.
İşlevsel diller, okunabilirlik açısından potansiyel bir avantaja sahiptir. birçoğunda
zorunlu programlar, değişkenlerle uğraşmanın ayrıntıları,
program. Küplerinin toplamını hesaplayan bir fonksiyon düşünün.
ilk n pozitif tam sayı. C'de, böyle bir işlev muhtemelen şuna benzer görünür:
devamındaki:
int toplam_küp( int n){
int toplam = 0;
for ( int dizin = 1; dizin <= n; dizin++)
toplam += dizin * dizin * dizin;
dönüş toplamı;
}
Haskell'de işlev şöyle olabilir:
sumCubes n = toplam (harita (^3) [1..n])

Sayfa 740
15.11 İşlevsel ve Zorunlu Dillerin Karşılaştırılması 719
Bu sürüm sadece üç adımı belirtir:
1. Sayıların listesini oluşturun ( [1..n] ).
2. Bir nesnenin küpünü hesaplayan bir işlevi eşleyerek yeni bir liste oluşturun.
numarayı listedeki her numaranın üzerine yerleştirin.
3. Yeni listeyi toplayın.
Değişkenlerin ayrıntılarının ve yineleme kontrolünün olmaması nedeniyle, bu sürüm
C versiyonundan daha okunaklı. 16
Zorunlu dillerde eşzamanlı yürütme tasarlamak zordur ve
13. Bölüm'de gördüğümüz gibi, kullanımı zor. Zorunlu bir dilde, pro-
dilbilgisi, programın statik bir bölümünü eşzamanlı bölümlerine ayırmalı,
bunlar daha sonra yürütülmesi genellikle senkronize edilmesi gereken görevler olarak yazılır.
Bu karmaşık bir süreç olabilir. İşlevsel dillerdeki programlar doğaldır.
ralli işlevlere ayrılmıştır. Saf bir işlevsel dilde, bu işlevler
yan etki yaratmamaları ve operasyonları açısından bağımsız
yerel olmayan veya global değişkenlere bağlı değildir. Bu nedenle, çok daha kolay
hangisinin aynı anda yürütülebileceğini belirlemek için. gerçek parametre
çağrılardaki ifadeler genellikle eşzamanlı olarak değerlendirilebilir. Basitçe belirterek
yapılabileceğini, bir işlevin ayrı bir iş parçacığında örtük olarak değerlendirilebileceğini,
Multilisp'te olduğu gibi. Ve elbette, paylaşılan değişmez verilere erişim,
senkronizasyon.
Zorunluluğun karmaşıklığını güçlü bir şekilde etkileyen basit bir faktör veya
prosedürel programlama, programcının gerekli dikkati
Programın gelişiminin her aşamasındaki durumu. Geniş bir programda,
programın durumu çok sayıda değerdir (çok sayıda pro-
gram değişkenleri). Saf fonksiyonel programlamada durum yoktur; bu nedenle, hayır
akılda tutmaya özen göstermelidir.
İşlevsel dillerin tam olarak neden işlevsel olduğunu belirlemek basit bir mesele değildir.
daha fazla popülerlik kazanmamıştır. Erken uygulamanın verimsizliği
o zamanlar açıkça bir faktördü ve muhtemelen en azından bazı çağdaş
Zorunlu programcılar hala programların işlevsel dilde yazılmış olduğuna inanıyor.
guajlar yavaş. Buna ek olarak, programcıların büyük çoğunluğu program-
işlevsel programların görünür olmasını sağlayan zorunlu dilleri kullanarak ming
garip ve anlaşılması güç olmalarıdır. Rahat olan birçok kişi için-
zorunlu programlama ile mümkün, fonksiyonel programlamaya geçiş
çekici olmayan ve potansiyel olarak zor bir hareket. Öte yandan, olanlar
işlevsel bir dille başlayın, işlevle ilgili garip bir şey fark etmeyin
ulusal programlar.
16. Tabii ki, C versiyonu daha işlevsel bir tarzda yazılabilirdi, ancak çoğu C pro-
gramerler muhtemelen bu şekilde yazmazlardı.

Sayfa 741
720
Bölüm 15 Fonksiyonel Programlama Dilleri
ÖZET
Matematiksel işlevler, yalnızca koşulları kullanan adlandırılmış veya adsız eşlemelerdir.
değerlendirmelerini kontrol etmek için ifadeler ve özyineleme. karmaşık fonksiyonlar
işlev gördüğü üst düzey işlevler veya işlevsel biçimler kullanılarak tanımlanabilir.
parametreler, döndürülen değerler veya her ikisi olarak kullanılır.
İşlevsel programlama dilleri, matematiksel işlevler üzerine modellenmiştir.
tion. Saf formlarında, değişkenler veya atama ifadeleri kullanmazlar.
sonuç üretmek; bunun yerine fonksiyon uygulamalarını, koşullu ifadeleri kullanırlar.
ve yürütme denetimi için özyineleme ve karmaşık oluşturmak için işlevsel formlar
fonksiyonlar. LISP, tamamen işlevsel bir dil olarak başladı, ancak kısa sürede
verimliliğini artırmak için eklenen bir dizi zorunlu dil özelliği
ve kullanım kolaylığı.
LISP'in ilk versiyonu, bir liste işleme programına duyulan ihtiyaçtan doğdu.
AI uygulamaları için guage. LISP hala bunun için en yaygın kullanılan dildir.
alan.
LISP'nin ilk uygulaması şans eseriydi: Orijinal versiyon
arasında EVAL evrensel LISP fonksiyonu göstermek için yalnızca geliştirildi
yazılabilirdi.
LISP verileri ve LISP programları aynı forma sahip olduğundan,
bir programın başka bir program oluşturmasını sağlamak. Kullanılabilirliği EVAL verir
anında yürütülecek dinamik olarak oluşturulmuş programlar.
Scheme, statik kapsam belirlemeyi hariç tutan nispeten basit bir LISP lehçesidir.
ısrarla. LISP gibi, Scheme'in birincil ilkelleri, yapılandırma için işlevleri içerir.
listeleri oluşturma ve sökme, koşullu ifadeler için işlevler ve basit
sayılar, semboller ve listeler için yüklemler.
Common LISP, aşağıdakileri içerecek şekilde tasarlanmış LISP tabanlı bir dildir.
1980'lerin başındaki LISP lehçelerinin özelliklerinin çoğu. Her ikisine de izin verir
statik ve dinamik kapsamlı değişkenler ve birçok zorunlu özellik içerir.
Ortak LISP, bazı işlevlerini tanımlamak için makrolar kullanır. Kullanıcılara izin verilir
kendi makrolarını tanımlamak için. Dil, okuyucu makrolarını içerir.
ayrıca kullanıcı tanımlı. Okuyucu makroları, tek sembollü makroları tanımlar.
ML, statik kapsamlı ve kesin olarak yazılmış bir işlevsel programlama dilidir
zorunlu bir dilinkiyle daha yakından ilişkili bir sözdizimi kullanan
LISP'den daha fazla. Bir tür çıkarım sistemi, istisna işleme, çeşitli
veri yapıları ve soyut veri türleri.
ML herhangi bir tür zorlama yapmaz ve fonksiyon aşırı yüklenmesine izin vermez.
ing. Model eşleştirmesi kullanılarak birden fazla fonksiyon tanımı tanımlanabilir.
gerçek parametre formu. Körleme, bir işlevi değiştirme işlemidir.
tek bir parametre alan ve bir
diğer parametreleri alan fonksiyon. ML'nin yanı sıra diğer birkaç işlevsel
diller, körlemeyi destekler.
Haskell, ML'ye benzer, ancak Haskell'deki tüm ifadeler değerlendirmeye tabidir.
programların sonsuz listelerle uğraşmasına izin veren tembel bir yöntem kullanılarak yapılmıştır.
Haskell ayrıca, kullanışlı ve

Sayfa 742
Soruları gözden geçir 721
kümeleri tanımlamak için tanıdık sözdizimi. ML ve Scheme'den farklı olarak Haskell, saf bir
Fonksiyonel dil.
F#, işlevsel ve emperyalizmi destekleyen bir .NET programlama dilidir.
nesne yönelimli programlama dahil olmak üzere tive programlama. İşlevsel pro-
graming çekirdeği, ML ve Haskell'in soyundan gelen OCaml'e dayanmaktadır. F#
ayrıntılı ve yaygın olarak kullanılan bir IDE tarafından desteklenir. Ayrıca diğerleriyle birlikte çalışır
.NET dilleri ve .NET sınıf kitaplığına erişimi vardır.
KAYNAKÇA NOTLAR
LISP'nin ilk yayınlanmış versiyonu McCarthy'de (1960) bulunabilir. geniş bir
1960'ların ortasından 1970'lerin sonlarına kadar kullanılan versiyon McCarthy'de açıklanmıştır.
ve diğerleri (1965) ve Weissman (1967). Ortak LISP, Steele'de (1990) anlatılmıştır.
Scheme dili Dybvig'de (2003) açıklanmıştır. ML, Milner'da tanımlanır
ve diğerleri (1990). Ullman (1998), makine öğrenimi için mükemmel bir giriş kitabıdır.
Haskell'de programlama Thompson'da (1999) tanıtılmıştır. F# anlatılıyor
Syme et al. (2010).
Bu bölümdeki Şema programları, DrRacket'in
eski dil R5RS.
Genel olarak işlevsel programlamanın titiz bir tartışması bulunabilir
Henderson'da (1980). İşlevsel dilleri uygulama süreci
graf indirgeme yoluyla ayrıntılı olarak Peyton Jones (1987)'de tartışılmıştır.
İNCELEME SORULARI
1. İşlevsel formu , basit listeyi , bağlı değişkeni ve referansı tanımlayın
şeffaflık .
2. Bir lambda ifadesi neyi belirtir?
3. Hangi veri türleri orijinal LISP'nin parçalarıydı?
4. LISP listeleri normalde hangi ortak veri yapısında saklanır?
5. Veri listesi olan bir parametre için QUOTE'un neden gerekli olduğunu açıklayın .
6. Basit liste nedir?
7. REPL kısaltması ne anlama geliyor?
8. IF'nin üç parametresi nelerdir ?
9. = , EQ arasındaki farklar nelerdir ? , EQV? ve EŞİT ?
10. Değerlendirme için kullanılan değerlendirme yöntemi arasındaki farklar nelerdir?
DEFINE özel formu ve ilkel işlevleri için kullanılan şema ?
11. DEFINE'ın iki biçimi nelerdir ?
12. COND'un sözdizimini ve anlamını tanımlayın .

Sayfa 743
722
Bölüm 15 Fonksiyonel Programlama Dilleri
13. CAR ve CDR neden böyle adlandırılıyor?
14. CONS iki atomla çağrılırsa, 'A ve 'B deyin , dönen nedir?
15. Scheme'de LET'in sözdizimini ve semantiğini tanımlayın .
16. CONS , LIST ve APPEND arasındaki farklar nelerdir ?
17. Scheme'deki mapcar'ın sözdizimini ve anlamını tanımlayın .
18. Kuyruk özyineleme nedir? kullanan işlevleri tanımlamak neden önemlidir?
Kuyruk özyinelemeli olmak için tekrarı belirtmek için özyineleme?
19. LISP'in çoğu lehçesine neden zorunlu özellikler eklendi?
20. Ortak LISP ve Şema hangi yönlerden zıttır?
21. Şemada hangi kapsam kuralı kullanılıyor? Ortak LISP'de? ML'de mi? İçinde
Haskell? F#'da mı?
22. Ortak LISP dilinin okuyucu aşamasında ne olur?
işlemci?
23. ML'nin Scheme'den temelde farklı olduğu iki yol nedir?
24. Bir ML değerlendirme ortamında neler saklanır?
25. Bir ML val ifadesi ile atama arasındaki fark nedir?
C'deki ifade?
26. Makine öğreniminde kullanıldığı şekliyle tür çıkarımı nedir?
27. ML'de fn ayrılmış word'ün kullanımı nedir ?
28. Skaler sayısallarla ilgilenen ML işlevleri genel olabilir mi?
29. Köri işlevi nedir?
30. Kısmi değerlendirme ne anlama geliyor?
31. ML filtre işlevinin eylemlerini tanımlayın .
32. ML, Scheme'in CAR'ı için hangi operatörü kullanıyor?
33. ML, işlevsel kompozisyon için hangi operatörü kullanır?
34. Haskell'i farklı kılan üç özelliği nelerdir?
ML'den mi?
35. Tembel değerlendirme ne anlama geliyor?
36. Katı bir programlama dili nedir?
37. F# hangi programlama paradigmalarını destekler?
38. F# başka hangi programlama dilleriyle birlikte çalışabilir?
39. F # 'ın ne geliyor bırakıldığında yukarı do?
40. Bir F# let yapısının kapsamı nasıl sonlandırılır?
41. F#'da bir dizi ile liste arasındaki temel fark nedir?
42. ML'nin let'i ile F#'nin let'i arasındaki fark nedir?
kapsam?
43. F#'da bir lambda ifadesinin sözdizimi nedir?
44. F# ifadelerde sayısal değerleri zorlar mı? Desteklemek için tartışmak
tasarım seçimi.

Sayfa 744
Problem Seti 723
45. Python, işlevsel programlama için hangi desteği sağlıyor?
46. ​​Curried işlevi oluşturmak için Ruby'de hangi işlev kullanılır?
47. İşlevsel programlamanın kullanımı genişliyor mu yoksa küçülüyor mu?
48. İşlevsel programlama dillerinin özelliklerinden biri nedir?
anlamlarını zorunlu dillerden daha basit hale getirir mi?
49. Üretkenliği karşılaştırmak için kod satırlarını kullanmanın kusuru nedir?
işlevsel diller ve zorunlu diller?
50. İşlevsel dillerde eşzamanlılık neden imperaliteden daha kolay olabilir?
diller?
PROBLEM SETİ
1. John Backus'un FP hakkındaki makalesini okuyun (Backus, 1978) ve karşılaştırın
Bu bölümde tartışılan Şema'nın özellikleri, ilgili
FP'nin özellikleri.
2. EVAL ve APPLY Şema fonksiyonlarının tanımlarını bulun ve açıklayın.
onların hareketleri.
3. En modern ve eksiksiz programlama ortamlarından biri
LISP için INTERLISP sistemi, “INTERLISP
Programlama Ortamı”, Teitelmen ve Masinter ( IEEE Com-
puter , Cilt. 14, No. 4, Nisan 1981). Bu makaleyi dikkatlice okuyun ve karşılaştırın
kullanarak sisteminizde LISP programları yazmanın zorluğu
INTERLISP (normalde INTERLISP kullanmadığınızı varsayarak).
4. LISP programlama üzerine bir kitaba bakın ve hangi argümanların olduğunu belirleyin.
PROG özelliğinin LISP'ye dahil edilmesini destekler .
5. Yazılı bir işlevsel programlama dilinin en az bir örneğini bulun.
Aşağıdakilerin her birinde ticari bir sistem oluşturmak için kullanılan gösterge
alanlar: veri tabanı işleme, finansal modelleme, istatistiksel analiz ve
biyo-informatik.
6. İşlevsel bir dil, liste dışında bazı veri yapılarını kullanabilir.
Örneğin, tek karakterli sembol dizilerini kullanabilir. Ne
böyle bir dilin CAR , CDR ve yerine ilkel
Scheme'in EKSİLERİ ilkelleri?
7. ML'de olmayan F# özelliklerinin bir listesini yapın.
8. Scheme salt işlevsel bir dil olsaydı, DISPLAY içerebilir mi?
Neden veya neden olmasın?
9. Aşağıdaki Şema işlevi ne işe yarar?
(tanımla (ys lis)
(koşul
((boş? lis) '() )

Sayfa 745
724
Bölüm 15 Fonksiyonel Programlama Dilleri
((eşit? s (araba lis)) lis)
(başka (ys (cdr lis)))
))
10. Aşağıdaki Scheme işlevi ne yapar?
(tanımla (x lis)
(koşul
((boş? lis) 0)
((değil (liste? (araba lis)))
(koşul
((eq? (araba lis) #f) (x (cdr lis)))
(başka (+ 1 (x (cdr lis))))))
(başka (+ (x (araba lis)) (x (cdr lis))))
PROGRAMLAMAALIŞTIRMALAR
1. Verilen bir kürenin hacmini hesaplayan bir Şema fonksiyonu yazın.
yarıçap.
2. Verilen bir qua-nin gerçek köklerini hesaplayan bir Scheme fonksiyonu yazın.
zor denklem. Kökler karmaşıksa, fonksiyon bir
olduğunu belirten mesaj. Bu işlev bir EĞER işlevi kullanmalıdır . bu
fonksiyonun üç parametresi, qua'nın üç katsayısıdır.
zor denklem.
3. Programlama Egzersizi 2'yi bir COND işlevi yerine bir COND işlevi kullanarak tekrarlayın.
EĞER işlevi.
4. A ve B olmak üzere iki sayısal parametre alan bir Şema işlevi yazın ,
ve yükseltilmiş A'yı B gücüne döndürür .
5. Verilen bir dizideki sıfırların sayısını döndüren bir Şema işlevi yazın.
basit sayı listesi.
6. Basit bir sayı listesi alan bir Scheme işlevi yazın.
parametre ve içindeki en büyük ve en küçük sayıları içeren bir liste döndürür
giriş listesi.
7. Bir liste ve bir atomu parametre olarak alan bir Scheme fonksiyonu yazın
ve tüm üst düzey hariç, parametre listesiyle aynı bir liste döndürür
verilen atomun örnekleri silindi.
8. Bir listeyi parametre olarak alan ve bir liste döndüren bir Scheme fonksiyonu yazın
son öğenin silinmesi dışında parametreyle aynıdır.
9. Programlama Alıştırması 7'yi tekrarlayın, ancak atom her ikisinden biri olabilir.
atom veya bir liste.

Sayfa 746
Programlama Alıştırmaları 725
10. Parametre olarak iki atom ve bir liste alan bir Scheme fonksiyonu yazın
ve tüm oluşumları dışında parametre listesiyle aynı bir liste döndürür
listede verilen ilk atom, verilen ikinci atomla değiştirilir,
ilk atom ne kadar derine yuvalanmış olursa olsun.
11. Basit listesinin tersini döndüren bir Scheme işlevi yazın
parametre.
12. Yapısal eşitliği test eden bir Şema yüklem fonksiyonu yazın
verilen iki listeden. Aynı özelliklere sahiplerse iki liste yapısal olarak eşittir
atomları farklı olsa da liste yapısı.
13. İki basit liste parametresinin birleşimini döndüren bir Scheme işlevi yazın.
kümeleri temsil eden eterler.
14. Bir atom ve bir liste olmak üzere iki parametreli bir Şema fonksiyonu yazın.
tüm oluşumlar dışında parametre listesiyle aynı bir liste döndürür,
ne kadar derin olursa olsun, verilen atom silinir. Döndürülen liste olamaz
silinen atomların yerine herhangi bir şey içerir.
15. Bir listeyi parametre olarak alan ve bir değer döndüren bir Scheme fonksiyonu yazın.
liste, ikinci üst düzey öğe hariç, parametre listesiyle aynıdır.
ment kaldırıldı. Verilen listede iki eleman yoksa fonksiyon
() dönmelidir .
16. Basit bir sayı listesi olarak alan bir Scheme fonksiyonu yazın.
parametre ve parametre listesiyle aynı olan bir liste döndürür.
sayılar artan sırada.
17. Parametresi olarak basit bir sayı listesi alan bir Scheme fonksiyonu yazın.
eter ve listedeki en büyük ve en küçük sayıları döndürür.
18. Parametresi olarak basit bir liste alan bir Scheme fonksiyonu yazın ve
verilen listenin tüm permütasyonlarının bir listesini döndürür.
19. Hızlı sıralama algoritmasını Scheme'e yazın.
20. Aşağıdaki Scheme işlevini kuyruk özyinelemeli bir işlev olarak yeniden yazın:
(TANIMLA (nokta n)
(EĞER (= n 0)
0
(+ n (nokta (− n 1)))
))
21. İlk 19 Programlama Alıştırmalarından herhangi birini F# ile yazın
22. Makine öğreniminde ilk 19 Programlama Alıştırmalarından herhangi birini yazın.

Sayfa 747
Bu sayfa bilerek boş bırakılmıştır

Sayfa 748
727
16.1 Giriş
16.2 Yüklem Analizine Kısa Bir Giriş
16.3 Yüklem Analizi ve Teoremleri Kanıtlama
16.4 Mantıksal Programlamaya Genel Bakış
16.5 Prolog'un Kökenleri
16.6 Prolog'un Temel Öğeleri
16.7 Prolog Eksiklikleri
16.8 Mantık Programlama Uygulamaları
16
Mantık Programlama
Diller

Sayfa 749
728
Bölüm 16 Mantık Programlama Dilleri
T Bu bölümün o hedefleri mantık programlama kavramlarını tanıtmak için vardır
ve mantık programlama dilleri, bir alt kümenin kısa bir tanımını içerir.
Prolog. Temel olan yüklem analizine bir girişle başlıyoruz.
mantık programlama dilleri için. Bunu, yüklemin nasıl hesaplandığına dair bir tartışma izler.
culus, otomatik teorem ispatlama sistemleri için kullanılabilir. Daha sonra genel bir
mantık programlamaya genel bakış. Daha sonra, uzun bir bölüm programın temellerini tanıtır.
Aritmetik, liste işleme ve izleme aracı dahil olmak üzere prolog programlama dili
programlarda hata ayıklamaya yardımcı olmak ve ayrıca Prolog sisteminin nasıl çalıştığını göstermek için kullanılabilir.
İşler. Son iki bölüm, Prolog'un bazı problemlerini bir mantık ağı olarak tanımlamaktadır.
kılavuzu ve Prolog'un kullanıldığı bazı uygulama alanları.
16.1 Giriş
15. Bölüm, işlevsel programlama paradigmasını tartışır.
ile kullanılan yazılım geliştirme metodolojilerinden önemli ölçüde farklıdır.
zorunlu diller. Bu bölümde, başka bir farklı pro-
gramer metodolojisi. Bu durumda yaklaşım, programları ifade etmektir.
sembolik bir mantık biçiminde ve üretmek için mantıksal bir çıkarım süreci kullanın.
Sonuçlar. Mantık programları prosedürel olmaktan çok bildirimseldir, yani
ayrıntılı değil, sadece istenen sonuçların spesifikasyonlarının belirtilmesi
bunları üretmek için prosedürler. Mantık programlama dillerinde programlar
gerçekler ve kurallar topluluğu. Böyle bir program, ona sorular sorarak kullanılır,
gerçeklere ve kurallara başvurarak yanıtlamaya çalışır. "Danışmanlık"
burada belki yanıltıcıdır, çünkü süreç bundan çok daha karmaşıktır.
kelime çağrıştırır. Problem çözmeye yönelik bu yaklaşım, kulağa hitap ettiği gibi gelebilir.
sadece çok dar bir problem kategorisidir, ancak olabileceğinden daha esnektir.
düşünülmeli.
Programlama dili olarak bir tür sembolik mantık kullanan programlama
genellikle mantıksal programlama olarak adlandırılır ve sembolik mantığa dayalı diller
denilen mantık programlama dilleri veya bildirim diller . Sahibiz
Mantıksal programlama dili Prolog'u tanımlamak için seçilmiştir, çünkü
sadece yaygın olarak kullanılan mantık dili.
Mantıksal programlama dillerinin sözdizimi, diğerlerinden oldukça farklıdır.
emir kipi ve işlevsel diller. Mantık pro-
gram ayrıca zorunlu dil programlarına çok az benzerlik gösterir.
Bu gözlemler okuyucuyu doğa hakkında biraz merak etmeye yöneltmelidir.
mantıksal programlama ve bildirimsel diller.
16.2 Yüklem Analizine Kısa Bir Giriş
Mantıksal programlamayı tartışmadan önce, kısaca onun temelini araştırmalıyız.
hangi biçimsel mantıktır. Bu, formel mantıkla ilk temasımız değil.
kitap; Bölüm 3'te açıklanan aksiyomatik anlambilimde yaygın olarak kullanılmıştır.

Sayfa 750
16.2 Yüklem Analizi 729'a Kısa Bir Giriş
Bir önerme , olabilecek veya olabilecek mantıksal bir ifade olarak düşünülebilir.
doğru olmasın. Nesnelerden ve nesneler arasındaki ilişkilerden oluşur. Resmi
mantık, önermeleri açıklamak için bir yöntem sağlamak için geliştirildi.
resmi olarak ifade edilen önermelerin geçerliliğinin kontrol edilmesini sağlama amacını güder.
Sembolik mantık , formel mantığın üç temel ihtiyacı için kullanılabilir:
önermeleri ifade etme, önermeler arasındaki ilişkileri ifade etme ve
yeni önermelerin diğer önermelerden nasıl çıkarsanabileceğini betimler.
doğru olduğu varsayılır.
Biçimsel mantık ile matematik arasında yakın bir ilişki vardır. İçinde
Aslında, matematiğin çoğu mantık açısından düşünülebilir. Temel-
sayı aksiyomları ve küme teorisi, ilk önermeler kümesidir.
doğru olduğu varsayılır. Teoremler, olabilecek ek önermelerdir.
ilk kümeden elde edilir.
Mantıksal programlama için kullanılan belirli bir sembolik mantık biçimi
birinci dereceden yüklem hesabı denir (biraz kesin olmasa da
genellikle yüklem hesabı olarak anılacaktır ). Aşağıdaki alt bölümlerde,
yüklem hesabına kısa bir bakış sunun. Amacımız temel atmak
mantık programlama ve mantık programlama dili hakkında bir tartışma için
Prolog.
16.2.1 Önermeler
Mantıksal programlama önermelerindeki nesneler basit olarak temsil edilir.
sabitler veya değişkenler olan terimler. Bir sabit, temsil eden bir semboldür.
bir nesneye içerler. Değişken, farklı nesneleri temsil edebilen bir semboldür.
farklı zamanlarda, bir anlamda matematiğe çok daha yakın olmasına rağmen
zorunlu bir programlama dilinde değişkenler.
Adlandırılır basit önermeler, atomik önerme , oluşmaktadır
bileşik terimler. Bir bileşik terimi, matematiksel bir elemanıdır
matematiksel fonksiyon görünümüne sahip bir biçimde yazılmış ilişki
notasyon. Bölüm 15'ten, matematiksel bir fonksiyonun bir haritalama olduğunu hatırlayın,
bu, bir ifade olarak veya bir tablo veya demet listesi olarak temsil edilebilir.
Bileşik terimler, bir fonksiyonun tablo şeklindeki tanımının öğeleridir.
Bir bileşik terim iki kısımdan oluşur: fonksiyon olan bir functor.
ilişkiyi adlandıran sembol ve sıralı bir parametre listesi,
birlikte ilişkinin bir öğesini temsil eder. Tek bir bileşik terim
parametre 1 demettir; biri iki parametreli bir 2 demetidir ve bu böyle devam eder. İçin
örneğin, iki önermeye sahip olabiliriz
adam ( jake )
gibi ( bob, biftek )
bu, {jake}'in man adlı ilişkide 1 demet olduğunu ve {bob,
biftek}, like adlı ilişkide bir 2 demettir. önermeyi eklersek
adam ( fred )

Sayfa 751
730
Bölüm 16 Mantık Programlama Dilleri
önceki iki önermeye göre, o zaman insan ilişkisinin iki farklı
elementler, {jake} ve {fred}. Bu önermelerdeki tüm basit terimler—insan,
jake, like, bob ve steak—sabitlerdir. Bu önermelerin hiçbir
içsel anlambilim. Biz ne demek istiyorsak onu kastediyorlar. Örneğin,
ikinci örnek, bob'un bifteği sevdiği veya bifteğin bob'u sevdiği anlamına gelebilir veya
o bob bir şekilde bifteğe benziyor.
Önermeler iki şekilde ifade edilebilir: Biri önermenin
doğru olarak tanımlanmış ve önermenin doğruluğunun bir şey olduğu
yani belirlenecek. Başka bir deyişle, önermeler gerçekler olarak ifade edilebilir.
veya sorgular. Örnek önermeler herhangi biri olabilir.
Bileşik önermeler iki veya daha fazla atomik önermeye sahiptir.
mantıksal bağlayıcılar veya operatörler tarafından aynı şekilde bileşik mantıkla bağlanır
ifadeler zorunlu dillerde oluşturulur. İsimler, semboller ve
yüklem hesabı mantıksal bağlaçlarının anlamları aşağıdaki gibidir:
Aşağıdakiler bileşik önermelere örnektir:
bir x bc
bir x ¬ bd
¬ operatörü en yüksek önceliğe sahiptir. x , h ve K operatörlerinin hepsinde
ve So'dan daha yüksek öncelik, ikinci örnek eşdeğerdir
(bir x (¬ b)) d
Değişkenler önermelerde görünebilirler, ancak yalnızca özel olarak tanıtıldıklarında.
niceleyiciler olarak adlandırılan sosyal semboller . Yüklem hesabı, aşağıdaki gibi iki niceleyici içerir:
aşağıda açıklanmıştır, burada X bir değişkendir ve P bir önermedir:
İsim
sembol
Örnek
Anlam
olumsuzlama
¬
¬ bir
değil bir
bağlaç
x
bir x b
a ve b
ayrılma
H
bir h b
a veya b
denklik
K
Bir K B
a , b'ye eşittir
Ima
ab
a b'yi ifade eder
ab
b ima bir
İsim
Örnek
Anlam
evrensel
5 x . P
Hepsi için X , P doğrudur.
varoluşsal
E X . P
Arasında bir değere duyulmaktadır X bu
bu P doğrudur.

Sayfa 752
16.2 Yüklem Analizi 731'e Kısa Bir Giriş
X ve P arasındaki nokta , değişkeni önermeden basitçe ayırır.
tion. Örneğin, aşağıdakileri göz önünde bulundurun:
5 x . ( kadın ( X ) insan ( X ))
E X . ( anne ( mary, X ) x erkek ( X ))
Bu önermelerden ilki, X'in herhangi bir değeri için , eğer X bir kadınsa,
o zaman X bir insandır. Arasında bir değere var olduğu ikinci araçlar X şekildedir
mary, X'in annesidir ve X bir erkektir; başka bir deyişle, Mary'nin bir oğlu var. bu
evrensel ve varoluşsal niceleyicilerin kapsamı, atomik önermelerdir.
hangi bağlılar. Bu kapsam, aşağıdaki gibi parantezler kullanılarak genişletilebilir:
az önce açıklanan iki bileşik önerme. Yani evrensel ve varoluşsal
niceleyiciler herhangi bir operatörden daha yüksek önceliğe sahiptir.
16.2.2 Cümle Formu
Mantıksal programlamanın temeli olduğu için yüklem hesabını tartışıyoruz.
Diller. Diğer dillerde olduğu gibi, mantık dilleri de en basit hallerinde en iyisidir.
fazlalığın en aza indirilmesi gerektiği anlamına gelir.
Şimdiye kadar tanımladığımız gibi yüklem hesabıyla ilgili bir sorun şudur:
aynı olan önermeleri ifade etmenin çok fazla farklı yolu vardır.
anlam; yani, çok fazla fazlalık var. Bu öyle bir sorun değil
mantıkçılar için, ancak yüklem hesabı otomatikleştirilmiş (bilgisayar-
ized) sisteminde ciddi bir sorundur. Konuları basitleştirmek için standart bir form
önermeler arzu edilir. Nispeten basit bir şekli olan klozal form
önermeler, böyle bir standart formdur. Tüm önermeler şu şekilde ifade edilebilir:
tümce formu. Cümle biçimindeki bir önerme aşağıdaki genel sözdizimine sahiptir:
B 1 h B 2 h . . . h B n
Bir 1 x bir 2 x . . . x A m
ki burada A ' S ve B' in terimlerdir. Bu yan tümce formunun anlamı
şöyle sition olup: her Eğer bir' s doğruysa, o zaman en az bir B geçerlidir.
Cümlesel form önermelerinin temel özellikleri şunlardır:
Varoluşsal niceleyiciler gerekli değildir; evrensel niceleyiciler örtük
atomik önermelerde değişkenlerin kullanımında; ve başka operatör yok
daha fazla bağlaç ve ayrılma gereklidir. Ayrıca, bağlaç ve ayrıl-
bağlantı ihtiyacı yalnızca genel yan tümce biçiminde gösterilen sırada görünür:
sol tarafta ayrılma ve sağ tarafta birleşme. tüm yüklem
kalkülüs önermeleri algoritmik olarak tümcesel forma dönüştürülebilir. Nils-
oğlu (1971), basit bir dönüştürmenin yanı sıra bunun yapılabileceğinin kanıtını verir.
Bunu yapmak için algoritma.
Cümlesel bir form önermesinin sağ tarafına öncül denir .
Sol tarafa sonuç denir, çünkü bu sonucun sonucudur.
öncül gerçeği. Cümlesel form önermelerinin örnekleri olarak, düşünün
devamındaki:
beğeniler ( bob, alabalık ) beğeniler ( bob, balık ) x balık ( alabalık )

Sayfa 753
732
Bölüm 16 Mantık Programlama Dilleri
baba ( louis, al ) h baba ( louis, menekşe )
baba ( al, bob ) x anne ( menekşe, bob ) x büyükbaba ( louis, bob )
Bunlardan ilkinin İngilizce versiyonu, eğer bob balık ve alabalık seviyorsa
balıksa, bob alabalığı sever. İkincisi, eğer al Bob'un babasıysa ve
menekşe bob'un annesi ve louis bob'un büyükbabası, o zaman louis ya al'ın
baba veya menekşe babası.
16.3 Yüklem Analizi ve Teoremleri Kanıtlama
Yüklem hesabı, önerme koleksiyonlarını ifade etmek için bir yöntem sağlar.
Önerme koleksiyonlarının bir kullanımı, herhangi bir ilgi çekici olup olmadığını belirlemektir.
veya faydalı gerçekler onlardan çıkarılabilir. Bu tam olarak işe benzer
çıkarılabilecek yeni teoremler keşfetmeye çalışan matematikçilerin
bilinen aksiyom ve teoremlerden
Bilgisayar biliminin ilk günleri (1950'ler ve 1960'ların başı) büyük bir gelişme gördü.
teorem kanıtlama sürecini otomatikleştirme ilgi anlaşması. En iyilerinden biri
otomatik teorem kanıtlamada önemli atılımlar keşif oldu
Syracuse Üniversitesi'nde Alan Robinson (1965) tarafından çözümleme ilkesi.
Çözünürlük , çıkarsanan önermelerin olmasına izin veren bir çıkarım kuralıdır.
verilen önermelerden hesaplanır, böylece potansiyele sahip bir yöntem sağlar.
otomatik teorem ispatına uygulama. Çözünürlük uygulanmak üzere tasarlandı
tümce biçiminde önermelere. Çözünürlük kavramı aşağıdaki gibidir:
Formlarla birlikte iki önerme olduğunu varsayalım.
p 1
P 2
S 1
Q, 2
Bunların anlamı olmasıdır p 2 ima P 1 ve Q, 2 ifade eder Q, 1 . Ayrıca, varsayalım
Bu p 1 ile aynıdır Q 2 biz adlandırmak böylece bu, P 1 ve Q 2 olarak T . Sonra biz
iki önermeyi şu şekilde yeniden yazabilir
TP 2
S 1
T
Şimdi, P 2 , T'yi ve T , Q 1'i ima ettiğinden, mantıksal olarak açıktır ki, P 2
olarak yazabileceğimiz Q 1 anlamına gelir
S 1
P 2
Bu önermeyi orijinal iki önermeden çıkarma süreci
çözünürlüktür.
Başka bir örnek olarak, iki önermeyi ele alalım:
daha yaşlı ( joanne, jake ) anne ( joanne, jake )
daha bilge ( joanne, jake ) daha yaşlı ( joanne, jake )
Bu önermelerden yola çıkarak aşağıdaki önerme oluşturulabilir:
çözüm:

Sayfa 754
16.3 Yüklem Analizi ve Teoremleri Kanıtlama 733
daha bilge ( joanne, jake ) anne ( joanne, jake )
Bu çözünürlük yapısının mekaniği basittir:
sol tarafı yapmak için iki yan tümceli önermenin sol tarafları VEYA birlikte kullanılır
yeni önermenin O zaman iki yan tümceli önermenin sağ tarafları
VE yeni önermenin doğru tarafını elde etmek için bir araya geldi. Daha sonra, herhangi bir terim
Her iki tarafta da görünen yeni önerme her iki taraftan da çıkarılır.
Önermeler birden fazla terime sahip olduğunda süreç tamamen aynıdır.
iki ya da iki tarafta. Yeni çıkarsanan önermenin sol tarafı başlangıçta
verilen iki önermenin sol taraflarının tüm terimlerini içerir. Yeni
sağ taraf da benzer şekilde inşa edilmiştir. O zaman her iki tarafta da görünen terim
yeni önerme kaldırıldı. Örneğin, eğer sahipsek
baba ( bob, jake ) h anne ( bob, jake ) ebeveyn ( bob, jake )
büyükbaba ( bob, fred ) baba ( bob, jake ) x baba ( jake, fred )
çözünürlük öyle diyor
anne ( bob, jake ) h büyükbaba ( bob, fred )
ebeveyn ( bob, jake ) x baba ( jake, fred )
orijinal önermelerin her ikisinin de atomik önermelerinden biri dışında tümüne sahip olan
yerler. Baba(bob,
jake) birincinin sol tarafında ve ikincinin sağ tarafında dışarıda bırakılmıştır.
İngilizce olarak söylerdik
eğer :
bob, jake'in ebeveynidir, bob'un ya baba ya da anne olduğunu ima eder
jake'in
ve : bob, jake'in babasıdır ve jake, fred'in babasıdır, bob'un
fred'in büyükbabası mı
o zaman : eğer bob jake'in ebeveyniyse ve jake de fred'in babasıysa : ya
bob, jake'in annesi veya bob, fred'in büyükbabasıdır.
Çözünürlük aslında bu basit örneklerin gösterdiğinden daha karmaşıktır.
Özellikle, önermelerdeki değişkenlerin varlığı, bulmak için çözüm gerektirir.
eşleştirme işleminin başarılı olmasına izin veren değişkenler için değerler. Bu profesyonel-
değişkenler için yararlı değerler belirleme işlemine birleştirme denir . tempo-
Birleştirmeye izin vermek için değişkenlere değerlerin nadiren atanmasına örnekleme denir .
Çözümleme işleminin bir değişkeni bir değişkenle başlatması yaygındır.
değer, gerekli eşleşmeyi tamamlayamadı ve ardından geri izlemesi istendi
ve değişkeni farklı bir değerle somutlaştırın. Birleşmeyi tartışacağız
ve Prolog bağlamında daha kapsamlı bir şekilde geri izleme.
Çözünürlüğün kritik derecede önemli bir özelliği, herhangi bir şeyi algılama yeteneğidir.
Belirli bir önermeler kümesindeki tutarsızlık. Bu, resmi prop-
çürütme tamamlandı denilen çözümlemenin erty'si . Bunun anlamı, verilen bir
Tutarsız önermeler kümesi, çözümleme onların tutarsız olduklarını kanıtlayabilir.
Bu, çözünürlüğün şu şekilde yapılabilecek teoremleri kanıtlamak için kullanılmasına izin verir:

Sayfa 755
734
Bölüm 16 Mantık Programlama Dilleri
aşağıdaki gibidir: Yüklem hesabı açısından bir teorem ispatını şu şekilde tasavvur edebiliriz:
teoremin kendisinin olumsuzlanmasıyla birlikte verilen bir dizi ilgili önerme
yeni bir önerme olarak ifade edilmiştir. Teorem reddedilir, böylece çözünürlük
bir tutarsızlık bularak teoremi kanıtlamak için kullanılabilir. Bu kanıt
çelişki, matematikte teoremleri kanıtlamak için sıklıkla kullanılan bir yaklaşım.
Tipik olarak, orijinal önermelere hipotezler denir ve olumsuzlar.
teoremin ifadesine hedef denir .
Teorik olarak bu süreç geçerli ve faydalıdır. Çözünürlük için gereken süre
ancak, sorun olabilir. Çözünürlük sonlu bir süreç olmasına rağmen
önermeler kümesi sonludur, bir önermede bir tutarsızlık bulmak için gereken süre
önermelerin büyük veri tabanı çok büyük olabilir.
Teorem kanıtlama, mantıksal programlamanın temelidir. Ne olduğunu çok
hesaplanan, verilen gerçeklerin ve ilişkilerin bir listesi şeklinde ifade edilebilir.
hipotezler olarak ve çözümleme kullanılarak hipotezlerden çıkarılacak bir amaç olarak.
Genel önermeler olan bir hipotez ve bir hedef üzerinde çözüm, hatta
Cümle biçimindeyse, genellikle pratik değildir. Mümkün olsa da
yan tümceli form önermelerini kullanarak bir teoremi kanıtlamak için, bu bir
makul bir süre. Çözüm sürecini basitleştirmenin bir yolu,
önermelerin biçimini kısıtlar. Yararlı bir kısıtlama,
önermeler Horn yan tümceleri olsun. Boynuz tümceleri yalnızca iki biçimde olabilir: Bunlar
sol tarafta tek bir atomik önermeye veya boş bir sol tarafa sahiptir. 1
Cümlesel bir form önermesinin sol tarafına bazen baş denir ve
Sol kenarlı boynuz cümlelere başlı Horn cümleleri denir. başlı boynuz
cümleleri ilişkileri belirtmek için kullanılır, örneğin
beğeniler ( bob, alabalık ) beğeniler ( bob, balık ) x balık ( alabalık )
Genellikle gerçekleri ifade etmek için kullanılan, sol tarafı boş olan boynuz cümleleri,
başsız Horn cümleleri denir . Örneğin,
baba ( bob, jake )
Önermelerin tümü olmasa da çoğu, Boynuz tümceleri olarak ifade edilebilir. Kısıtlı-
Horn yan tümcelerine geçiş, çözümü teoremleri kanıtlamak için pratik bir süreç haline getirir.
16.4 Mantıksal Programlamaya Genel Bakış
Mantıksal programlama için kullanılan dillere bildirimsel diller denir , çünkü
içlerinde yazılan programlar, atamalardan ziyade bildirimlerden oluşur ve
kontrol akışı ifadeleri. Bu beyanlar aslında ifadeler veya önermelerdir.
sembolik mantıkta.
Mantıksal programlama dillerinin temel özelliklerinden biri,
bildirimsel anlambilim olarak adlandırılan anlambilim . Bunun temel konsepti
anlambilim, her bir durumun anlamını belirlemenin basit bir yolu olmasıdır.
ve bu, ifadenin bir sorunu çözmek için nasıl kullanılabileceğine bağlı değildir.
1. Boynuz tümceleri, bu formdaki tümceleri inceleyen Alfred Horn'un (1951) adını almıştır.

Sayfa 756
16.4 Mantıksal Programlamaya Genel Bir Bakış 735
sorun. Bildirim semantiği, ifadenin semantiğinden çok daha basittir.
zorunlu diller. Örneğin, belirli bir önermenin anlamı
mantıksal programlama dili, ifadeden kısaca belirlenebilir
kendisi. Zorunlu bir dilde, basit bir atama ifadesinin anlamı
yerel beyannamelerin incelenmesini,
dil ve muhtemelen caydırmak için diğer dosyalardaki programların incelenmesi bile
atama ifadesindeki değişkenlerin türlerini araştırın. Daha sonra, varsayarak
atamanın ifadesi değişkenleri içerir, programın yürütülmesi
değerleri belirlemek için atama ifadesinden önce izlenmelidir.
değişkenler. O halde, ifadenin sonuç eylemi, çalışma zamanına bağlıdır.
bağlam. Bu anlambilimi bir mantık dilindeki bir önermenin anlambilimiyle karşılaştırarak,
metinsel bağlamı veya yürütme dizilerini dikkate almaya gerek kalmadan,
bildirimsel anlambilim, zorunlu dillerin anlambiliminden çok daha basittir.
Bu nedenle, bildirimsel anlambilim genellikle bildirimin avantajlarından biri olarak belirtilir.
tif diller, emredici dillerden fazladır (Hogger, 1984, s. 240–241).
Hem zorunlu hem de işlevsel dillerde programlama öncelikle pro-
cedural, programcının neyin başarılacağını bildiği anlamına gelir
bir program tarafından ve bilgisayara hesaplamanın tam olarak nasıl yapılacağı konusunda talimat verir.
yapıldı. Başka bir deyişle, bilgisayar, kurallara uyan basit bir aygıt olarak ele alınır.
emirler. Hesaplanan her şey, o hesaplamanın her ayrıntısına sahip olmalıdır.
hecelemek. Bazıları, programlamanın zorluğunun özünün bu olduğuna inanıyor.
zorunlu ve işlevsel diller kullanarak ming.
Mantıksal programlama dilinde programlama prosedürel değildir. programlar
bu tür dillerde bir sonucun tam olarak nasıl hesaplanacağını belirtmez, bunun yerine
sonucun şeklini açıklayın. Aradaki fark, bilgisayarı varsaymamızdır.
sistem bir şekilde sonucun nasıl hesaplanacağını belirleyebilir. İhtiyaç duyulan şey
mantık programlama dilleri için bu yeteneği sağlamak, kısa ve öz bir araçtır.
bilgisayara hem ilgili bilgileri hem de bir çıkarım yöntemi sağlamak.
İstenen sonuçları hesaplamak için Yüklem hesabı, temel biçimi sağlar
bilgisayara iletişim ve çözünürlük, çıkarım tekniğini sağlar.
Prosedürel arasındaki farkı göstermek için yaygın olarak kullanılan bir örnek.
ve prosedürel olmayan sistemler sıralamadır. Java gibi bir dilde sıralama yapılır
bir sıralama algoritmasının tüm ayrıntılarını bir Java programında açıklayarak
Java derleyicisi olan bir bilgisayar. Java'yı çevirdikten sonra bilgisayar
makine koduna veya bazı yorumlayıcı ara kodlara programlayın,
yönergeleri ve sıralanmış listeyi üretir.
Prosedürel olmayan bir dilde, sadece karakter-
sıralanmış listenin özellikleri: Verilen listenin bazı permütasyonları, her biri için
Bitişik eleman çifti, belirli bir ilişki iki eleman arasında tutar.
Bunu resmi olarak belirtmek için, sıralanacak listenin list adında bir dizide olduğunu varsayalım.
bir alt simge aralığına sahiptir 1 . . . n . Verilen öğeleri sıralama kavramı
old_list adlı liste ve bunları new_list adlı ayrı bir diziye yerleştirmek,
sonra aşağıdaki gibi ifade edilir:
Sıralama ( old_list, new_list ) permute ( old_list, new_list ) x sıralanmış ( new_list )
( list ) 5j 1 … j 6 n, list(j) … list(j + 1) olacak şekilde sıralanır

Sayfa 757
736
Bölüm 16 Mantık Programlama Dilleri
burada permute, ikinci parametre dizisi ise true değerini döndüren bir yüklemdir.
ilk parametre dizisinin bir permütasyonu.
Bu açıklamadan, prosedürel olmayan dil sistemi,
sıralanmış listeyi oluştur. Bu, prosedürel olmayan programlamayı
sadece kısa ve öz yazılım gereksinimleri spesifikasyonlarının üretimi, ki bu
adil değerlendirme Ancak ne yazık ki, bu o kadar basit değil. mantık programları
yalnızca çözünürlüğü kullananlar, yürütme verimliliği konusunda ciddi sorunlarla karşı karşıyadır. bizim
sıralama örneği, liste uzunsa, permütasyon sayısı çok fazladır ve
sırayla olana kadar tek tek oluşturulmalı ve test edilmelidir.
bulunur - çok uzun bir süreç. tabiki ihtimali de düşünmek lazım
bir mantık dilinin en iyi biçiminin henüz belirlenmemiş olabileceğini ve
büyük için mantıksal programlama dillerinde programlar oluşturmanın iyi yöntemleri
sorunlar henüz gelişmemiştir.
16.5 Prolog'un Kökenleri
Bölüm 2'de belirtildiği gibi, Alain Colmerauer ve Phillippe Roussel,
Aix-Marsilya Üniversitesi, Robert Kowalski'nin yardımıyla
Edinburgh Üniversitesi, Prolog'un temel tasarımını geliştirdi.
Colmerauer ve Roussel, doğal dil işleme ile ilgilendiler ve
Kowalski, otomatik teorem ispatıyla ilgileniyordu. işbirliği
Aix-Marseille Üniversitesi ile Edinburgh Üniversitesi arasında
1970'lerin ortalarına kadar sürdü. O zamandan beri, geliştirme ve kullanım üzerine araştırma
dilin bu iki yerde bağımsız olarak ilerlemiş olması,
diğer şeylerin yanı sıra, Prolog'un sözdizimsel olarak farklı iki lehçesinde.
Mantık programında Prolog ve diğer araştırma çabalarının geliştirilmesi-
ming, Edinburgh ve Marsilya dışında sınırlı ilgi gördü.
1981'de Japon hükümetinin büyük bir
Beşinci Nesil Hesaplama Sistemleri (FGCS; Fuchi,
1981; Moto-oka, 1981). Projenin temel hedeflerinden biri,
akıllı makineler geliştirdi ve bu çabanın temeli olarak Prolog seçildi.
FGCS'nin duyurusu araştırmacılarda ve hükümetlerde uyandırdı.
Amerika Birleşik Devletleri ve birkaç Avrupa ülkesinde ani bir güçlü ilgi
yapay zeka ve mantık programlama.
On yıllık bir çabanın ardından, FGCS projesi sessizce bırakıldı. Aksine
mantık programlamanın ve Prolog'un büyük varsayılan potansiyeli, çok az büyük
önemi keşfedilmişti. Bu da ilginin azalmasına neden oldu ve
Prolog'un kullanımı, yine de uygulamaları ve savunucuları olmasına rağmen.
16.6 Prolog'un Temel Öğeleri
Artık Prolog'un birkaç farklı lehçesi var. Bunlar gruplandırılabilir
birkaç kategoriye ayrılır: Marsilya grubundan büyüyenler,
Edinburgh grubundan geldi ve geliştirilen bazı lehçeler

Sayfa 758
16.6 Prolog 737'nin Temel Öğeleri
Clark tarafından açıklanan mikro-Prolog gibi mikrobilgisayarlar için ve
McCabe (1984). Bunların sözdizimsel biçimleri biraz farklıdır. Yerine
Prolog'un birkaç lehçesinin veya bazı melez lehçelerin sözdizimini tanımlamaya çalışmak yerine
Bunlardan, belirli, yaygın olarak bulunan bir lehçe seçtik, o da
biri Edinburgh'da geliştirildi. Dilin bu formu bazen denir
Edinburg sözdizimi . İlk uygulaması bir DEC System-10 (Warren
ve diğerleri, 1979). Hemen hemen tüm popüler iletişim için prolog uygulamaları mevcuttur.
örneğin, Free Software Organisation'dan ( http://
www.gnu.org) .
16.6.1 Şartlar
Diğer dillerdeki programlarda olduğu gibi, Prolog programları da koleksiyonlardan oluşur.
ifadeler. Prolog'da yalnızca birkaç tür ifade vardır, ancak bunlar
karmaşık olabilir. Tüm Prolog deyimi ve ayrıca Prolog verileri oluşturulur
terimlerden.
Bir Prolog terimi bir sabit, bir değişken veya bir yapıdır. Bir sabit ya
bir atom veya bir tamsayı. Atomlar Prolog'un sembolik değerleridir ve benzerdir.
LISP'deki muadillerine. Özellikle, bir atom ya bir harf dizisidir,
küçük harf veya herhangi bir karakter dizisi ile başlayan rakamlar ve alt çizgiler
kesme işaretiyle ayrılmış yazdırılabilir ASCII karakterleri.
Değişken, ile başlayan herhangi bir harf, rakam ve alt çizgi dizisidir.
büyük harf veya alt çizgi ( _ ). Değişkenler türlere bağlı değildir
beyanlar. Bir değerin ve dolayısıyla bir türün bir değişkene bağlanmasına bir değişken denir.
somutlaştırma . Örnekleme yalnızca çözümleme sürecinde gerçekleşir. Bir değişken
bir değer atanmamış, uninstantiated olarak adlandırılır . Örneklemeler son
kanıtını içeren tek bir tam hedefi yerine getirmek için gerekli olduğu sürece
ya da bir önermenin çürütülmesi. Prolog değişkenleri yalnızca uzak akrabalardır,
hem semantik hem de kullanım terimleri, zorunlu dillerdeki değişkenlere.
Son tür terime yapı denir . Yapılar atomu temsil eder
yüklem hesabının önermeleri ve genel biçimleri aynıdır:
functor ( parametre listesi )
İşlev, herhangi bir atomdur ve yapıyı tanımlamak için kullanılır. parametre listesi
atomların, değişkenlerin veya diğer yapıların herhangi bir listesi olabilir. Uzun uzun tartışıldığı gibi
Aşağıdaki alt bölümde, yapılar Prolog'da gerçekleri belirtmenin araçlarıdır.
Ayrıca nesneler olarak da düşünülebilirler, bu durumda gerçeklerin gerçek olmasına izin verirler.
birkaç ilgili atom cinsinden ifade edilir. Bu anlamda yapılar ilişkilerdir,
çünkü terimler arasındaki ilişkileri ifade ederler. Bir yapı aynı zamanda bir yüklem olduğunda
bağlamı bunun bir sorgu (soru) olduğunu belirtir.
16.6.2 Olgu Açıklamaları
Prolog ifadelerine ilişkin tartışmamız, aşağıdaki ifadelerle başlar:
hipotezleri veya varsayılan bilgilerin veri tabanını yapılandırın - ifadeler
hangi yeni bilgiler çıkarılabilir.

Sayfa 759
738
Bölüm 16 Mantık Programlama Dilleri
Prolog'un iki temel ifade formu vardır; bunlar başsızlara karşılık gelir ve
yüklem hesabının başlı Boynuz yan tümceleri. Başsız Boynuz'un en basit hali
Prolog'daki yan tümce, koşulsuz olarak yorumlanan tek bir yapıdır.
iddia veya gerçek. Mantıksal olarak, olgular basitçe,
Gerçek olmak.
Aşağıdaki örnekler, bir Pro-
günlük programı. Her Prolog ifadesinin bir nokta ile sonlandırıldığına dikkat edin.
dişi (kabuk).
erkek (fatura).
dişi (mary).
erkek (jake).
baba(bil, jake).
baba(bill, shelley).
anne(mary, jake).
anne(mary, shelley).
Bu basit yapılar , jake , shelley , bill ve
mary . Örneğin, ilki shelley'nin bir dişi olduğunu belirtir . son dört
iki parametresini functor'da adlandırılan bir ilişkiyle bağlayın
atom; örneğin, beşinci önerme şu şekilde yorumlanabilir:
Tasarı olan baba arasında Jake . Bu Prolog önermelerinin, bunlar gibi
yüklem hesabının içsel semantiği yoktur. ne olursa olsun demek istiyorlar
programcı onları demek istiyor. Örneğin, önerme
baba(bil, jake).
anlamına gelebilir faturası ve Jake aynı olması babaya ya da Jake olan baba
bir tasarı . Bununla birlikte, en yaygın ve anlaşılır anlam,
Bu tasarı olduğu baba arasında Jake .
16.6.3 Kural Açıklamaları
Veritabanı doğrulamasını oluşturmak için Prolog ifadesinin diğer temel biçimi.
başlı Horn cümlesine karşılık verir. Bu form bilinen bir teoremle ilişkilendirilebilir.
Verilen koşullar kümesi varsa, bir sonucun çıkarılabileceği matematik
memnun. Sağ taraftaki öncül, ya eğer parçası ve sol tarafı
sonuç olarak veya daha sonra bölüm. Bir Prolog ifadesinin öncülü doğruysa, o zaman
ifadesinin sonucu da doğru olmalıdır. Horn cümleleri oldukları için,
Bir Prolog ifadesinin sonucu tek bir terimdir, öncül ise
tek bir terim veya bir bağlaç olabilir.
Bağlaçlar , mantıksal AND ile ayrılmış birden çok terim içerir.
operasyonlar. Prolog'da AND işlemi ima edilir. olan yapılar
atomik önermeleri bir arada belirtin, virgülle ayrılır, bu nedenle
virgüllerin AND operatörleri olduğunu düşünebilir. Konjonktür örneği olarak
için şunları göz önünde bulundurun:

Sayfa 760
16.6 Prolog 739'un Temel Öğeleri
kadın(shelley), çocuk(shelley).
Prolog başlıklı Horn yan tümcesi ifadesinin genel biçimi şöyledir:
sonuç :- öncül_ifade.
Şöyle okunur: “Önceki ifadenin ifade edilmesi halinde sonuç çıkarılabilir.
sion doğrudur veya değişkenlerinin bir miktar somutlaştırılmasıyla doğru hale getirilebilir.”
Örneğin,
ata(mary, shelley):- anne(mary, shelley).
eğer devletler mary olan anne ve shelley ardından mary bir olan atası arasında
Shelley . Headed Horn cümleciklerine kurallar denir çünkü kuralları belirtirler.
önermeler arasındaki çıkarım.
Yüklem hesabındaki tümcesel form önermelerinde olduğu gibi, Prolog ifadeleri
anlamlarını genelleştirmek için değişkenleri kullanabilir. Cümle içindeki değişkenleri hatırlayın
form, bir tür örtük evrensel niceleyici sağlar. Aşağıdaki şeytan-
Prolog ifadelerinde değişkenlerin kullanımını belirler:
ebeveyn(X, Y) :- anne(X, Y).
ebeveyn(X, Y) :- baba(X, Y).
grandparent(X, Z) :- parent(X, Y) , parent(Y, Z).
Bu ifadeler, bazı değişkenler veya evrensel arasında ima kuralları verir.
nesneler. Bu durumda, evrensel nesneler X , Y ve Z'dir . İlk kural diyor
bir örneklemi varsa bu , X ve Y bu şekilde anne (x, y) , daha sonra doğru
bu aynı örneklemesi için X ve Y , üst (X, Y) doğrudur.
= Bir infix operatörü operatör, başarılı iki dönem kaldığı bir işletim durumunda
ve'ler aynı. Örneğin, X = Y . Olmayan bir tekli operatör,
operatörü, işleneni başarısız olursa başarılı olması anlamında işlenenini tersine çevirir.
Örneğin, not(X = Y) , X , Y'ye eşit değilse başarılı olur .
16.6.4 Hedef Açıklamaları
Buraya kadar mantıksal önermeler için Prolog ifadelerini tanımladık.
mantıksal ilişkiyi tanımlayan hem bilinen gerçekleri hem de kuralları tanımlamak için kullanılır.
gerçekler arasında gemiler. Bu ifadeler teorem kanıtlamanın temelidir.
modeli. Teorem, sistemi istediğimiz bir önerme biçimindedir.
kanıtlamak veya çürütmek için. Prolog'da bu önermelere hedefler veya
sorgular . Prolog hedef ifadelerinin sözdizimsel biçimi,
başsız Horn cümleleri. Örneğin, biz olabilir
adam (fred).
sistemin evet veya hayır olarak yanıt vereceği . cevap evet demek
sistem, verilen gerçekler veritabanı altında hedefin doğru olduğunu kanıtladı ve

Sayfa 761
740
Bölüm 16 Mantık Programlama Dilleri
ilişkiler. Hayır cevabı , hedefin belirlendiği anlamına gelir.
false veya sistem bunu kanıtlayamadı.
Bağlaç önermeleri ve değişkenli önermeler de yasaldır.
hedefler. Değişkenler mevcut olduğunda, sistem yalnızca
amacı değil, aynı zamanda hedefi oluşturan değişkenlerin örneklerini de tanımlar.
doğru. Örneğin,
baba(X, mike).
sorulabilir. Sistem daha sonra birleştirme yoluyla bir
hedef için gerçek bir değerle sonuçlanan X'in somutlaştırılması .
Çünkü amaç ifadeleri ve bazı amaçsız ifadeler aynı forma sahiptir.
(başsız Horn cümleleri), bir Prolog uygulamasının bazı araçları olması gerekir
ikisi arasında ayrım yapmak. Etkileşimli Prolog uygulamaları bunu yapar
farklı etkileşimli istemlerle gösterilen iki moda sahip olarak: bir
olgu ve kural ifadelerini girmek için ve bir tane de hedefleri girmek için. kullanıcı
modu istediğiniz zaman değiştirin.
16.6.5 Girişin Çıkarım Süreci
Bu bölümde Prolog çözünürlüğü incelenir. Prolog'un verimli kullanımı şunları gerektirir:
programcı, Prolog sisteminin kendi yazılımıyla ne yaptığını tam olarak bilir.
programı.
Sorgulara hedefler denir . Bir amaç bir bileşik önerme olduğunda, her biri
olgulara (yapılara) alt hedef denir . Bir amacın doğru olduğunu kanıtlamak için çıkarım-
süreç, veritabanında bir çıkarım kuralları ve/veya gerçekler zinciri bulmalıdır.
hedefi veritabanındaki bir veya daha fazla gerçeğe bağlayın. Örneğin, eğer Q ise
hedef, o zaman ya Q , veri tabanında bir gerçek olarak bulunmalıdır ya da çıkarım pro-
Cess bir gerçek bulmalı P 1 ve önermeler bir dizi P 2 , p 3 , c, p , n şekildedir
P 2 : - P 1
P 3 - p 2
. . .
S : - Pn
Tabii ki, süreç bileşik kurallarla karmaşık olabilir ve çoğu zaman karmaşıktır.
değişkenli sağ taraflar ve kurallar. P s'yi bulma süreci , ne zaman onlar
var, temelde terimlerin birbirleriyle karşılaştırılması veya eşleştirilmesidir.
Çünkü bir alt amacı kanıtlama işlemi bir önerme yoluyla yapılır.
eşleştirme işlemine bazen eşleştirme denir . Bazı durumlarda kanıtlama
alt hedef, bu alt hedefi tatmin etmek olarak adlandırılır .
Aşağıdaki sorguyu göz önünde bulundurun:
adam (bob).
Bu hedef ifadesi en basit türdür. Çözünürlük için nispeten kolaydır
doğru mu yanlış mı olduğunu belirleyin: Bu hedefin modeli, aşağıdakilerle karşılaştırılır:
veritabanındaki gerçekler ve kurallar. Veritabanı gerçeği içeriyorsa

Sayfa 762
16.6 Prolog 741'in Temel Öğeleri
adam (bob).
kanıt önemsizdir. Bununla birlikte, veritabanı aşağıdaki gerçeği içeriyorsa ve
çıkarım kuralı,
baba (bob).
adam(X) :- baba(X).
Bu iki ifadeyi bulmak ve bunları çıkarım yapmak için kullanmak için Prolog gerekli olacaktır.
hedefin gerçeği. Bu, X'i başlatmak için birleştirmeyi gerektirecektir.
geçici olarak bob için .
Şimdi hedefi düşün
adam(X).
Bu durumda Prolog, verideki önermelerle hedefi eşleştirmelidir.
temel. Hedef biçimine sahip olduğunu bulduğu ilk önerme, herhangi bir
parametresi olarak nesne, X'in o nesnenin değeriyle somutlaştırılmasına neden olur .
Sonuç olarak X görüntülenir. şeklinde bir önerme yoksa
hedef, sistem hayır diyerek amacın gerçekleştirilemeyeceğini belirtir .
Belirli bir hedefi eşleştirmeye çalışmak için iki zıt yaklaşım vardır.
veritabanındaki bir gerçeğe. Sistem, sistemin gerçekleri ve kuralları ile başlayabilir.
veritabanı ve hedefe götüren bir dizi eşleşme bulmaya çalışın. Bu
yaklaşım aşağıdan yukarıya çözünürlük veya ileriye doğru zincirleme olarak adlandırılır . alterna-
Amaçla başlamak ve eşleşen bir dizi teklif bulmaya çalışmaktır.
veritabanında bazı orijinal gerçeklere yol açan durumlar. Bu yaklaşım
olarak adlandırılır yukarıdan aşağıya çözünürlük ya da geriye doğru zincirleme . Genel olarak geriye
zincirleme, oldukça küçük bir aday cevap seti olduğunda iyi çalışır.
İleri zincirleme yaklaşımı, olası doğru sayısı olduğunda daha iyidir.
cevaplar büyük; bu durumda, geriye doğru zincirleme çok büyük bir
Bir cevaba ulaşmak için eşleşme sayısı. Prolog uygulamaları geriye doğru kullanır
Çözüm için zincirleme, muhtemelen tasarımcıları geriye doğru inandıkları için
zincirleme, ileri zincirlemeden daha büyük bir problem sınıfı için daha uygundu.
Aşağıdaki örnek, ileri ve
geri zincirleme. Sorguyu düşünün:
adam (bob).
Veritabanının içerdiğini varsayalım
baba (bob).
adam(X) :- baba(X).
İleri zincirleme ilk önermeyi arar ve bulur. Amaç
daha sonra birinci önermeyi bölümün sağ tarafıyla eşleştirerek çıkarsama yapılır.
ond kural ( baba (X) nesnelleştirilmesi aracılığıyla) X için bob sonra ve eşleme
hedefe ikinci önermenin sol tarafı. Önce geriye zincirleme

Sayfa 763
742
Bölüm 16 Mantık Programlama Dilleri
hedefi ikinci önermenin ( man(X) ) sol tarafıyla eşleştirin
örneğinin X için bob . Son adım olarak, sağ tarafla eşleşirdi.
ikinci önerme (şimdi baba(bob) ) birinci önermeyle birlikte.
Bir sonraki tasarım sorusu, hedef birden fazla olduğunda ortaya çıkar.
yapısı, örneğimizde olduğu gibi. O zaman soru, çözüm arayışının olup olmadığıdır.
önce derinlik veya önce genişlik yapılır. Bir derinlik öncelikli arama komple bulur
üzerinde çalışmadan önce ilk alt hedef için önermeler dizisi - bir kanıt
diğerleri. Bir genişlik öncelikli arama, belirli bir amacın bütün alt hedefler üzerinde çalışır
paralel. Prolog'un tasarımcıları öncelikle derinlik yaklaşımını seçtiler çünkü
daha az bilgisayar kaynağı ile yapılabilir. Genişlik öncelikli yaklaşım,
büyük miktarda bellek gerektirebilecek paralel arama.
Prolog'un çözümleme mekanizmasının tartışılması gereken son özelliği
geri adım atıyor. Birden çok alt hedefi olan bir hedef işlenirken ve
sistem alt hedeflerden birinin gerçeğini gösteremezse, sistem terk eder
kanıtlayamadığı alt hedef. Daha sonra, varsa önceki alt hedefi yeniden değerlendirir.
biridir ve ona alternatif bir çözüm bulmaya çalışır. Bu yedekleme
önceden kanıtlanmış bir alt hedefin yeniden değerlendirilmesi amacına geri denir.
izleme . Bir öncekinin olduğu yerde arama başlatılarak yeni bir çözüm bulunur.
o alt hedefin aranması durduruldu. Bir alt hedefe yönelik birden çok çözüm,
değişkenlerinin farklı örneklemeleri. Geri izleme çok fazla şey gerektirebilir
zaman ve mekan, çünkü her alt amaca olası tüm kanıtları bulmak zorunda kalabilir.
Bu alt hedef kanıtları, gereken süreyi en aza indirecek şekilde düzenlenemez.
daha da kötüleştiren nihai tam kanıtla sonuçlanacak olanı bulmak için
sorun.
Geri izleme anlayışınızı sağlamlaştırmak için aşağıdakileri göz önünde bulundurun
örnek. Bir veri tabanında bir dizi olgu ve kural olduğunu varsayalım ve
Prolog aşağıdaki bileşik hedefle sunulmuştur:
erkek(X), ebeveyn(X, shelley).
Bu hedef bir instantiation olup olmadığını sorar X şekildedir X'in bir olan erkek
ve X, a, üst bölgesinin Shelley . Prolog, ilk adımı olarak ilk gerçeği şurada bulur:
functor olarak erkek olan veritabanı . Daha sonra X parametresini başlatır
bulunan gerçeğin, mike deyin . Daha sonra ebeveyn(mike,
Shelley) doğrudur. Başarısız olursa, ilk alt hedefe geri döner, male(X) ve
X'in bazı alternatif örneklemeleriyle onu yeniden tatmin etmeye çalışır . Çözünürlük
süreç , birini bulmadan önce veritabanındaki her erkeği bulmak zorunda kalabilir.
bu ise ebeveyn arasında shelley . Bunu kanıtlamak için kesinlikle tüm erkekleri bulmalı
hedef tatmin edilemez. Örnek hedefimizin işlenebileceğini unutmayın
iki alt hedefin sırası tersine çevrilirse daha verimli olur. Sonra, sadece sonra
Karar , Shelley'nin bir ebeveynini bulmuş olsaydı, o kişiyle eşleşmeye çalışır mıydı?
ile erkek althedefin. Shelley'nin daha az ebeveyni varsa bu daha verimlidir.
makul bir varsayım gibi görünen veritabanında erkek s olduğundan daha fazla
tion. Bölüm 16.7.1 tarafından yapılan geri izlemeyi sınırlama yöntemini tartışır.
bir Prolog sistemi.
Prolog'daki veritabanı aramaları her zaman ilkten sona doğru ilerler.

Sayfa 764
16.6 Prolog 743'ün Temel Öğeleri
Aşağıdaki iki alt bölüm, daha fazla açıklayıcı olan Prolog örneklerini açıklamaktadır.
çözüm sürecini değerlendirin.
16.6.6 Basit Aritmetik
Prolog, tamsayı değişkenlerini ve tamsayı aritmetiğini destekler. Başlangıçta, arit-
metic operatörler toplamı böylece, functors edildi 7 ve değişken X oldu
ile oluşturulmuş
+(7, X)
Prolog artık is ile aritmetik için daha kısaltılmış bir sözdizimine izin veriyor.
Şebeke. Bu operatör, sağ işleneni olarak bir aritmetik ifade alır ve
sol işleneni olarak bir değişken. İfadedeki tüm değişkenler zaten olmalıdır
somutlaştırılabilir, ancak sol taraftaki değişken önceden somutlaştırılamaz. İçin
örnek, içinde
A , B / 17 + C'dir.
eğer B ve C örneklenen ama bir değil, o zaman bu hüküm neden olur A olmak
ifadenin değeri ile somutlaştırılır. Bu gerçekleştiğinde, madde
memnun. Ya Eğer B veya C örneği değil veya bir örneği, madde olan
memnun değil ve A'nın hiçbir somut örneği gerçekleşemez. Bir anlamsallığı IS
önerme, bir atama ifadesinden önemli ölçüde farklıdır.
zorunlu bir dil. Bu fark ilginç bir senaryoya yol açabilir.
Çünkü olduğunu operatör beğenme göz göründüğü maddesini yapar
atama bildirimi, yeni başlayan bir Prolog programcısı için cazip olabilir
gibi bir ifade yazın
Toplam , Toplam + Sayıdır.
Prolog'da asla yararlı, hatta yasal olmayan. Eğer Sum örneği değil,
sağ taraftaki referans tanımsızdır ve yan tümce başarısız olur. Eğer Sum zaten
somutlaştırıldığında, yan tümce başarısız olur, çünkü sol işlenen bir akıma sahip olamaz.
örnekleme zaman olduğu değerlendirilir. Her iki durumda da, örneğinin Sum için
yeni değer gerçekleşmeyecek. ( Sum + Number değeri isteniyorsa,
bazı yeni adlara bağlı olabilir.)
Prolog, impera ile aynı anlamda atama ifadelerine sahip değildir.
diller. Programlamanın çoğunda bunlara ihtiyaç duyulmaz.
hangi Prolog tasarlanmıştır. İmper- 'de atama ifadelerinin kullanışlılığı
ative dilleri genellikle programcının kontrol etme yeteneğine bağlıdır.
atama ifadesinin bulunduğu kodun yürütme kontrol akışı
gömülü. Prolog'da bu tür bir kontrol her zaman mümkün olmadığı için,
ifadeler çok daha az kullanışlıdır.
Prolog'da sayısal hesaplama kullanımına basit bir örnek olarak, con-
Aşağıdaki problemi ele alalım: Birkaç aracın ortalama hızını bildiğimizi varsayalım.

Sayfa 765
744
Bölüm 16 Mantık Programlama Dilleri
belirli bir yarış pistindeki otomobiller ve üzerinde bulundukları süre
parça. Bu temel bilgiler gerçekler olarak kodlanabilir ve ilişki
hız, zaman ve mesafe arasında aşağıdaki gibi bir kural olarak yazılabilir:
hız(ford, 100).
hız(chevy, 105).
hız(kaçmak, 95).
hız(volvo, 80).
zaman(ford, 20).
zaman(chevy, 21).
zaman(kaçmak, 24).
zaman(volvo, 24).
mesafe(X, Y):- hız(X, Hız),
zaman(X, Zaman),
Y ise Hız * Zaman.
Artık sorgular belirli bir arabanın kat ettiği mesafeyi talep edebilir. İçin
örnek, sorgu
mesafe(chevy, Chevy_Distance).
Chevy_Distance'ı 2205 değeriyle başlatır .
mesafe hesaplama ifadesinin sağ tarafı, Hız değişkenlerini somutlaştırır
ve Verilen otomobil functorunun karşılık gelen değerleriyle Zaman . Sonrasında
Hedefi karşılayan Prolog, Chevy_Distance adını ve değerini de görüntüler .
Bu noktada, bir Prolog'un nasıl çalıştığına operasyonel bir bakış atmak öğreticidir.
sistem sonuç üretir. Prolog, trace adlı yerleşik bir yapıya sahiptir.
deneme sırasında her adımda değerlerin örneklemelerini değişkenlere oynatır.
belirli bir hedefi tatmin etmek. trace , Prolog programlarını anlamak ve hatalarını ayıklamak için kullanılır.
İzlemeyi anlamak için, yürütmenin farklı bir modelini tanıtmak en iyisidir.
izleme modeli olarak adlandırılan Prolog programları .
İzleme modeli, Prolog yürütmesini dört olay açısından tanımlar: (1)
bir hedefi gerçekleştirme girişiminin başlangıcında meydana gelen çağrı, (2) çıkış, hangi
bir hedef yerine getirildiğinde meydana gelir, (3) tekrar, geriye doğru gidildiğinde meydana gelir
bir hedefi yeniden tatmin etme girişimine neden olur ve (4) başarısızlığa uğrar;
başarısız olur. Çağrı ve çıkış, doğrudan bir alt programın yürütme modeliyle ilişkilendirilebilir.
mesafe gibi süreçler olarak düşünülürse, zorunlu bir dilde gram
alt programlar. Diğer iki olay, mantıksal programlama sistemlerine özgüdür.
Aşağıdaki izleme örneğinde, için değerin hesaplanmasının bir izi
Chevy_Distance , hedef tekrarlama veya başarısızlık olayları gerektirmez:
iz.
mesafe(chevy, Chevy_Distance).
(1) 1 Çağrı: mesafe(chevy, _0)?
(2) 2 Çağrı: hız(chevy, _5)?

Sayfa 766
16.6 Prolog 745'in Temel Öğeleri
(2) 2 Çıkış: hız(chevy, 105)
(3) 2 Çağrı: zaman(chevy, _6)?
(3) 2 Çıkış: zaman(chevy, 21)
(4) 2 Çağrı: _0 105*21 mi?
(4) 2 Çıkış: 2205, 105*21
(1) 1 Çıkış: mesafe(chevy, 2205)
Chevy_Mesafe = 2205
Alt çizgi karakteri ( _ ) ile başlayan izlemedeki semboller
somutlaştırılmış değerleri depolamak için kullanılan dahili değişkenler. İzlemenin ilk sütunu
şu anda eşleşmeye çalışılan alt hedefi gösterir. Örneğin,
örnek izlemede, (3) işaretli ilk satır,
_6 geçici değişkenini chevy için bir zaman değeriyle somutlaştırın , burada
zamanı tanımlayan ifadenin sağ tarafındaki ikinci terimdir.
mesafenin hesaplanması . İkinci sütun, arama derinliğini gösterir.
eşleştirme süreci. Üçüncü sütun, geçerli eylemi gösterir.
Geri izlemeyi göstermek için aşağıdaki örnek veritabanını göz önünde bulundurun ve
izlenen bileşik hedef:
seviyor(jake, çikolata).
seviyor(jake, kayısı).
sever(darcie, meyankökü).
seviyor(darcie, kayısı).
iz.
seviyor(jake, X), seviyor(darcie, X).
(1) 1 Çağrı: beğenir(jake, _0)?
(1) 1 Çıkış: beğeniler(jake, çikolata)
(2) 1 Çağrı: beğeni(darcie, çikolata)?
(2) 1 Başarısız: beğeniler(darcie, çikolata)
(1) 1 Yinele: beğeniler(jake, _0)?
(1) 1 Çıkış: beğeniler(jake, kayısı)
(3) 1 Çağrı: beğeniler(darcie, kayısı)?
(3) 1 Çıkış: beğeniler(darcie, kayısı)
X = kayısı
Prolog hesaplamaları grafiksel olarak şu şekilde düşünülebilir:
her hedef, dört bağlantı noktasına sahip bir kutu olarak - ara, başarısız, çık ve yinele. Kontrol girer
Çağrı portu aracılığıyla ileri yönde hedef. Kontrol ayrıca bir
yineleme portu aracılığıyla ters yönden gol. Kontrol de bırakabilir
iki şekilde bir hedef: Hedef başarılı olursa, kontrol çıkış kapısından ayrılır;
hedef başarısız olursa, kontrol başarısız bağlantı noktasından ayrılır. Örnek bir model
Şekil 16.1'de gösterilmiştir. Bu örnekte, kontrol her bir alt hedeften geçer

Sayfa 767
746
Bölüm 16 Mantık Programlama Dilleri
iki kere. İkinci alt hedef ilk seferde başarısız olur ve bu da geri dönüşü zorlar.
ilk alt hedefe tekrarla.
16.6.7 Liste Yapıları
Şimdiye kadar tartıştığımız tek Prolog veri yapısı atomik prop-
Bir veri yapısından daha çok bir işlev çağrısına benzeyen görev. atomik
Yapı olarak da adlandırılan önermeler aslında bir tür kayıttır.
Desteklenen diğer temel veri yapısı listedir. Listeler, herhangi bir
elementlerin atomlar, atomik önermeler veya
diğer listeler de dahil olmak üzere diğer şartlar.
Prolog, listeleri belirtmek için ML ve Haskell sözdizimini kullanır. Liste öğeleri
virgülle ayrılır ve tüm liste köşeli parantezlerle sınırlandırılır,
de olduğu gibi
[elma, erik, üzüm, kamkat]
Gösterimi [] boş listesini göstermek için kullanılır. Açık sözlü olmak yerine
listeleri oluşturmak ve dağıtmak için işlevler, Prolog sadece özel bir
notasyon. [X | Y] baş X ve kuyruk Y içeren bir listeyi belirtir ; burada baş ve kuyruk
LISP'deki CAR ve CDR'ye karşılık gelir . Bu, kullanılan gösterime benzer
ML ve Haskell.
Aşağıdaki gibi basit bir yapı ile bir liste oluşturulabilir.
new_list([elma, kuru erik, üzüm, kamkat]).
bu, sabit listenin [elma, kuru erik, üzüm, kamkat] bir
ilişkinin new_list adlı yeni öğesi (az önce oluşturduğumuz bir ad). Bu
deyim, listeyi yeni_liste adlı bir değişkene bağlamaz ; daha doğrusu yapar
teklifin ne tür bir şey olduğu
Şekil 16.1
Kontrol akış modeli
gol beğenileri için
(jake, X), beğeniler
(darcie, X)
beğeniler (jake, X)
beğeniler (darcie, X)
Telefon etmek
Başarısız
Telefon etmek
Başarısız
çıkış
yinele
çıkış
yinele

Sayfa 768
16.6 Prolog 747'nin Temel Öğeleri
erkek (jake)
yapmak. Yani [elma, erik, üzüm, kamkat] yeni bir
new_list öğesinin öğesi . Bu nedenle, ikinci bir önermeye sahip olabiliriz.
gibi liste argümanı
new_list([kayısı, şeftali, armut])
Sorgu modunda, new_list'in öğelerinden biri kafaya ayrılabilir.
ve kuyruk ile
new_list([New_List_Head | New_List_Tail]).
Eğer new_list gösterildiği gibi, bu devlet iki öğe var olarak ayarlandı
ment, New_List_Head öğesini ilk liste öğesinin başıyla başlatır (içinde
bu durumda, elma ) ve listenin kuyruğuyla New_List_Tail (veya [erik,
üzüm, kamkat] ). Bu, bileşik bir hedefin ve geri izlemenin bir parçası olsaydı
bunun yeni bir değerlendirmesini zorladı New_List_Head ve New_List_Tail olur
için reinstantiated edilebilir kayısı ve [şeftali, armut] için, sırasıyla
[kayısı, şeftali, armut] , new_list öğesinin sonraki öğesidir .
| Listeleri sökmek için kullanılan operatör ayrıca listeler oluşturmak için de kullanılabilir.
verilen örneklenmiş baş ve kuyruk bileşenleri,
[Element_1 | Liste_2]
Eğer Element_1 ile başlatılamaz edilmiş turşu ve List_2 instan- olmuştur
ile tiated [fıstık, kuru erik, patlamış mısır] , örnek gösterim için, yaratacak
bu bir referans, liste [turşu, fıstık, kuru erik, patlamış mısır] .
Daha önce belirtildiği gibi, | sembol evrenseldir
sal: Liste yapımını veya liste sökme işlemini belirtebilir. Daha fazla not edin
aşağıdakilerin eşdeğer olduğunu:
[kayısı, şeftali, armut | []]
[kayısı, şeftali | [armut]]
[kayısı | [şeftali, armut]]
Listelerde, bulunanlar gibi belirli temel işlemler genellikle gereklidir.
LISP, ML ve Haskell'de. Prolog'da bu tür işlemlere örnek olarak,
LISP'de böyle bir fonksiyonla ilgili olan append tanımını inceleyin . İçinde
bu örnekte, işlevsel ve bildirimsel arasındaki farklar ve benzerlikler
diller görülebilir. Prolog'un nasıl yeni bir yapı inşa edeceğini belirtmemize gerek yok.
verilen listelerden liste; bunun yerine, yalnızca özellikleri belirtmemiz gerekir.
verilen listeler açısından yeni liste.
Görünüşte, eklemenin Prolog tanımı ML'ye çok benzer.
Bölüm 15'te görünen sürüm ve çözünürlükte bir tür özyineleme kullanılıyor
yeni listeyi oluşturmak için benzer bir şekilde. Prolog durumunda, özyineleme

Sayfa 769
748
Bölüm 16 Mantık Programlama Dilleri
Çözüm süreci tarafından oluşturulur ve kontrol edilir. ML ve Haskell'de olduğu gibi,
gerçek parametreye göre seçim yapmak için bir model eşleştirme işlemi kullanılır,
ekleme işleminin iki farklı tanımı arasında.
Aşağıdaki kodda ekleme işleminin ilk iki parametresi
eklenecek iki listedir ve üçüncü parametre sonuç listesidir:
ekle([], Liste, Liste).
ekleme([Kafa | Liste_1], Liste_2, [Kafa | Liste_3]) :-
ekle(Liste_1, Liste_2, Liste_3).
İlk önerme, boş liste herhangi bir listeye eklendiğinde şunu belirtir:
diğer liste, bu diğer liste sonuçtur. Bu ifade şuna karşılık gelir:
ML ekleme işlevinin özyineleme sonlandırma adımı . Unutmayın ki ter-
Sonlandırıcı önerme, özyineleme önermesinden önce yer alır. Bu bitti
çünkü Prolog'un iki önermeyi sırayla eşleştireceğini biliyoruz, başla-
birincisiyle (derinlik birinci dereceden kullanılmasından dolayı).
İkinci önerme, yeni listenin çeşitli özelliklerini belirtir. o
ML işlevindeki özyineleme adımına karşılık gelir. Sol taraftaki yüklem
yeni listenin ilk öğesinin, listenin ilk öğesiyle aynı olduğunu belirtir.
ilk verilen liste, çünkü her ikisi de Head olarak adlandırılır . Her ne zaman Kafa instanti- olduğunu
bir değere ated, tüm tekrarları Başkanı golü, aslında, aynı anda vardır
bu değere örneklenir. İkinci ifadenin sağ tarafı şunu belirtir:
ilk verilen listenin kuyruğu (List_1) ikinci verilen listeye (List_2) sahiptir
sonuç listesinin kuyruğunu (List_3) oluşturmak için buna eklenir .
İkinci ekleme ifadesini okumanın bir yolu aşağıdaki gibidir:
listeyi oluşturma [Baş | List_1] herhangi bir listeye List_2 listesini üretir [Head
| List_3] , ancak liste halinde List_3 ekleyerek oluşturulur list_1 için
Liste_2 . LISP'de, bu
(EKSİLER (ÖNCE ARABA) (EKLER (İLK CDR) İKİNCİ))
Hem Prolog hem de LISP sürümlerinde, sonuç listesi şu ana kadar oluşturulmaz.
özyineleme, sonlandırma koşulunu üretir; bu durumda, ilk liste
boş hale gelmek. Ardından, sonuçtaki liste, ekleme işlevinin kendisi kullanılarak oluşturulur;
birinci listeden alınan elemanlar ikinciye ters sırada eklenir.
liste. Tersine çevirme, özyinelemenin çözülmesiyle yapılır.
Prolog en arasındaki temel farkı , ekleme yapılması ve LISP olanlar
ve ML Prolog en olmasıdır ekleme bunun bir yüklem-it listesini dönmez ise
evet veya hayır döndürür . Yeni liste, üçüncü parametresinin değeridir.
Ekleme işleminin nasıl ilerlediğini göstermek için aşağıdakileri göz önünde bulundurun
izlenen örnek:
iz.
ekle([bob, jo], [jake, darcie], Aile).
(1) 1 Çağrı: ekle([bob, jo], [jake, darcie], _10?

Sayfa 770
16.6 Prolog 749'un Temel Öğeleri
(2) 2 Çağrı: ekle([jo], [jake, darcie], _18)?
(3) 3 Çağrı: ekle([], [jake, darcie], _25)?
(3) 3 Çıkış: ekleme([], [jake, darcie], [jake, darcie])
(2) 2 Çıkış: ekleme([jo], [jake, darcie], [jo, jake,
darcie])
(1) 1 Çıkış: ekleme([bob, jo], [jake, darcie],
[bob, jo, jake, darcie])
Aile = [bob, jo, jake, darcie]
Evet
Alt hedefler temsil İlk iki çağrıları, sahip list_1 bu kadar, nonempty
ikinci ifadenin sağ tarafından özyinelemeli çağrıları oluşturun. bu
ikinci ifadenin sol tarafı etkin bir şekilde argümanları belirtir.
özyinelemeli çağrılar veya hedefler, böylece ilk listeyi adım başına bir öğe olarak dağıtır.
Bir çağrıda veya alt hedefte ilk liste boşaldığında, geçerli örnek
ikinci ifadenin sağ tarafı, ilk durumu eşleştirerek başarılı olur-
ment. Bunun etkisi, üçüncü parametre olarak parametrenin değerini döndürmektir.
ikinci orijinal parametre listesine eklenen boş liste. Ardışık çıkışlarda,
başarılı eşleşmeleri temsil eden, kaldırılan öğeler
ilk liste, ortaya çıkan listeye eklenir, Aile . çıkış yapıldığında
ilk hedefe ulaşıldı, süreç tamamlandı ve ortaya çıkan liste
görüntülenir.
Prolog en arasındaki bir diğer fark , ekleme yapılması ve LISP ve ML olanlar ise
Prolog en o ekleme o dillere göre daha fazla esnektir. Sınav için-
ple, Prolog'da hangi iki listenin eklenebileceğini belirlemek için ekleme kullanabiliriz
GET : [a, b, c] ile
ekle(X, Y, [a, b, c]).
Bu, aşağıdakilerle sonuçlanır:
X = []
Y = [a, b, c]
Bu çıktıya noktalı virgül yazarsak, alternatif sonucu alırız:
X = [a]
Y = [b, c]
Devam edersek, aşağıdakileri elde ederiz:
X = [a, b]
Y = [c];
X = [a, b, c]
Y = []

Sayfa 771
750
Bölüm 16 Mantık Programlama Dilleri
Ekleme yüklem de, diğer liste oluşturma işlemleri için kullanılabilir
Aşağıdaki gibi, etkisini okuyucuyu belirlemeye davet ediyoruz. Not
bu list_op_2 , ilk parametresi olarak bir liste sağlayarak kullanılmak içindir.
ve ikinci olarak bir değişken, ve sonucu list_op_2 değerdir
ikinci parametre somutlaştırılır.
list_op_2([], []).
list_op_2([Baş | Kuyruk], Liste):-
list_op_2(Kuyruk, Sonuç), append(Sonuç, [Baş], Liste).
Belirleyebileceğiniz gibi, list_op_2 Prolog sistemine neden olur.
ikinci parametresini listenin öğelerini içeren bir listeyle somutlaştırmak için
ilk parametrenin, ancak ters sırada. Örneğin, ([elma, portakal,
üzüm], Q) Q'yu [üzüm, portakal, elma] listesiyle başlatır .
Bir kez daha, LISP ve Prolog dilleri temelde
farklı, benzer işlemler benzer yaklaşımları kullanabilir. durumunda
Bu işlemin tersi, her iki Prolog en list_op_2 ve LISP en ters fonksiyonellik
temel süreçle birlikte özyinelemeyi sonlandırma koşulunu içerir.
CDR'nin tersine çevrilmesinin veya listenin kuyruğunun CAR'a veya Genel Müdürlük başkanına eklenmesi
sonuç listesini oluşturmak için liste.
Aşağıdaki, şimdi ters olarak adlandırılan bu işlemin bir izidir :
iz.
ters([a,b,c],Q).
(1) 1 Çağrı: ters([a, b, c], _6)?
(2) 2 Çağrı: ters([b, c], _65636)?
(3) 3 Çağrı: ters([c], _65646)?
(4) 4 Çağrı: geri([], _65656)?
(4) 4 Çıkış: ters([], [])
(5) 4 Çağrı: ekle([], [c], _65646)?
(5) 4 Çıkış: ekleme([], [c], [c])
(3) 3 Çıkış: ters([c], [c])
(6) 3 Çağrı: ekle([c], [b], _65636)?
(7) 4 Çağrı: ekle([], [b], _25)?
(7) 4 Çıkış: ekle([], [b], [b])
(6) 3 Çıkış: ekleme([c], [b], [c, b])
(2) 2 Çıkış: ters([b, c], [c, b])
(8) 2 Çağrı: ekle([c, b], [a], _6)?
(9) 3 Çağrı: ekle([b], [a], _32)?
(10) 4 Çağrı: ekle([], [a], _39)?
(10) 4 Çıkış: ekleme([], [a], [a])
(9) 3 Çıkış: ekleme([b], [a], [b, a])
(8) 2 Çıkış: ekleme([c, b], [a], [c, b, a])
(1) 1 Çıkış: ters([a, b, c], [c, b, a])
S = [c, b, a]

Sayfa 772
16.7 Prolog 751'in Eksiklikleri
Belirli bir sembolün bir yerde olup olmadığını belirleyebilmemiz gerektiğini varsayalım.
verilen liste. Bunun basit bir Prolog açıklaması
üye(Öğe, [Öğe | _]).
üye(Öğe, [_ | Liste]) :- üye(Öğe, Liste).
Alt çizgi, "anonim" bir değişkeni gösterir; demek için kullanılır
birleşmeden ne tür somut örnekler alabileceği umurumuzda değil. İlk
Önceki örnekteki ifade, Element listenin başındaysa başarılı olur ,
ya başlangıçta ya da ikinci ifadeyle birkaç özyinelemeden sonra. bu
Öğe listenin sonundaysa ikinci ifade başarılı olur . Yi hesaba kat
aşağıdaki izlenen örnekler:
iz.
üye(a, [b, c, d]).
(1) 1 Çağrı: üye(a, [b, c, d])?
(2) 2 Çağrı: üye(a, [c, d])?
(3) 3 Çağrı: üye(a, [d])?
(4) 4 Çağrı: üye(a, [])?
(4) 4 Başarısız: üye(a, [])
(3) 3 Başarısız: üye(a, [d])
(2) 2 Başarısız: üye(a, [c, d])
(1) 1 Başarısız: üye(a, [b, c, d])
Hayır
üye(a, [b, a, c]).
(1) 1 Çağrı: üye(a, [b, a, c])?
(2) 2 Çağrı: üye(a, [a, c])?
(2) 2 Çıkış: üye(a, [a, c])
(1) 1 Çıkış: üye(a, [b, a, c])
Evet
16.7 Prolog Eksiklikleri
Prolog faydalı bir araç olmasına rağmen, ne saf ne de mükemmel bir mantık programı değildir.
gramer dili. Bu bölümde Prolog ile ilgili bazı sorunlar açıklanmaktadır.
16.7.1 Çözünürlük Sırası Kontrolü
Prolog, verimlilik nedenleriyle, kullanıcının patinaj sırasını kontrol etmesine izin verir.
çözünürlük sırasında sumru eşleştirme. Saf bir mantıksal programlama ortamında,
Çözünürlük sırasında gerçekleşen eşleşme girişimlerinin sırası değişmez
ministic ve tüm eşleşmeler aynı anda denenebilir. Ancak, çünkü
Prolog, verilerin başlangıcından başlayarak her zaman aynı sırada eşleşir.
baz ve belirli bir hedefin sol ucunda, kullanıcı verimliliği derinden etkileyebilir

Sayfa 773
752
Bölüm 16 Mantık Programlama Dilleri
belirli bir uygulamayı optimize etmek için veritabanı ifadelerini sipariş ederek. İçin
örneğin, kullanıcı belirli kuralların başarılı olma olasılığının çok daha yüksek olduğunu biliyorsa
belirli bir "yürütme" sırasında diğerlerinden daha sonra program yapılabilir
bu kuralları veritabanında ilk sıraya yerleştirerek daha verimli.
Kullanıcının veritabanını ve alt hedef sırasını kontrol etmesine izin vermenin yanı sıra-
Prolog, verimlilikten başka bir tavizde, bazı açık kontrollere izin verir.
geri adım atmaktan. Bu, bir tarafından belirtilen kesme operatörü ile yapılır.
ünlem işareti ( ! ). Kesme operatörü aslında bir operatör değil, bir hedeftir. Olarak
hedef, her zaman hemen başarılı olur, ancak geri dönüş yoluyla yeniden tatmin edilemez.
izleme. Bu nedenle, kesmenin bir yan etkisi, bir bileşikte solundaki alt hedeflerin
hedef aynı zamanda geri izleme yoluyla da tatmin edilemez. Örneğin, hedefte
a, b, !, c, d.
hem eğer bir ve b başarılı ama c başarısız, tüm hedef başarısız olur. Bu hedef kullanılacak
Bu her ne zaman bilinseydi c edememesi durumunda, bu resatisfy zaman kaybıdır b ya da bir .
O zaman kesmenin amacı, kullanıcının programları daha fazla yapmasına izin vermektir.
alt hedefleri yeniden karşılamaya çalışmaması gerektiğini sisteme bildirerek verimli
bu muhtemelen tam bir kanıtla sonuçlanamazdı.
Cut operatörünün kullanımına bir örnek olarak, üye kurallarını göz önünde bulundurun.
Bölüm 16.6.7'den:
üye(Öğe, [Öğe | _]).
üye(Öğe, [_ | Liste]) :- üye(Öğe, Liste).
Liste argümanı ise üyesi bir dizi temsil, o zaman sadece tatmin edilebilir
bir kez (kümeler yinelenen öğe içermez). Bu nedenle, üye olarak kullanılırsa
birden çok alt hedef ifadesinde alt hedef, bir sorun olabilir. bu
sorun şu ki, üye başarılı olur, ancak bir sonraki alt hedef başarısız olursa, geri izleme
önceki bir eşleşmeye devam ederek üyeyi yeniden memnun etmeye çalışın . Ama liste çünkü
üyeye argüman , başlangıçta öğenin yalnızca bir kopyasına sahiptir, üye
tekrar başarılı olamaz, bu da sonunda tüm hedefin başarısız olmasına neden olur,
üyeyi yeniden memnun etmek için yapılan ek girişimlere rağmen . Örneğin, düşünün
amaç:
dem_candidate(X) :- üye(X, demokratlar), testler(X).
Bu hedef, belirli bir kişinin demokrat olup olmadığını ve iyi bir insan olup olmadığını belirler.
belirli bir pozisyon için aday olacak. Test oluşturulan alt çekleri çeşitli
uygunluğunu belirlemek için verilen demokratın özelliklerinin
pozisyon için kişi. Demokratlar kümesinin kopyası yoksa, o zaman biz
Testler alt hedefi başarısız olursa üye alt hedefine yedeklemek istemez ,
çünkü üye diğer tüm demokratları arayacak ama başarısız olacak, çünkü orada
kopyaları yoktur. Üye alt hedefinin ikinci girişimi ,
hesaplama süresi. Bu verimsizliğe çözüm, bir sağ taraf eklemektir.
tek olarak cut operatörü ile üye tanımının ilk ifadesi
öğesi, olduğu gibi

Sayfa 774
16.7 Prolog 753'ün Eksiklikleri
üye(Öğe, [Öğe | _]) :- !.
Geri izleme, üyeyi yeniden memnun etmeye çalışmaz, bunun yerine
başarısız olmak için tüm alt hedef.
Kesim Prolog'da bir programlama stratejisi denilen özellikle yararlıdır kaydıyla, jeneratör
kurun ve test edin . Oluştur ve test stratejisini kullanan programlarda amaç
Potansiyel çözümler üreten ve daha sonra kontrol edilen alt hedeflerden oluşur.
daha sonra "test" alt hedefleri ile. Reddedilen çözümler "jeneratöre" geri izleme gerektirir
yeni potansiyel çözümler üreten alt hedefler. Bir üretim örneği olarak-
ve test programı, Clocksin ve Mel'de görünen aşağıdakileri göz önünde bulundurun.
lehçe (2003):
böl(N1, N2, Sonuç):- is_integer(Sonuç),
Ürün1 Sonuç * N2'dir,
Ürün2 (Sonuç + 1) * N2,
Ürün1 =< N1, Ürün2 >
N1, !.
Bu program, toplama ve çarpma işlemlerini kullanarak tamsayı bölme işlemini gerçekleştirir.
Çoğu Prolog sistemi operatör olarak bölme sağladığından, bu program
basit bir oluştur ve test programını göstermek dışında aslında yararlı değildir.
is_integer yüklemi , parametresi kullanılabildiği sürece başarılı olur.
negatif olmayan bir tamsayıya örneklendi. Argümanı somutlaştırılmazsa,
is_integer onu 0 değerine başlatır.
integer, is_integer onu bir sonraki daha büyük tamsayı değerine başlatır.
Yani, içinde ayrımın , is_integer jeneratör oluşturulan alt olduğunu. Ele- üretir
0, 1, 2, … dizisinin mentleri, her tatmin edildiğinde bir tane. diğer hepsi
alt hedefler, test alt hedefleridir; değerin olup olmadığını belirlemek için kontrol ederler.
is_integer tarafından üretilen aslında ilk iki parametrenin bölümüdür ,
N1 ve N2 . Son alt hedef olarak kesmenin amacı basittir:
bulduktan sonra alternatif bir çözüm bulmaya çalışmaktan ayırın .
çözüm. Her ne kadar is_integer adayların çok sayıda oluşturabilir,
çözüm sadece bir tanesidir, bu yüzden buradaki kesim, işe yaramaz üretme girişimlerini önler.
ikincil çözümler.
Kesim operatörünün kullanımı, hatalı uygulamalarda goto kullanımı ile karşılaştırılmıştır.
yaratıcı diller (van Emden, 1980). Bazen ihtiyaç duyulsa da,
kötüye kullanmak mümkün. Gerçekten de, bazen mantık programlarının bir
zorunlu programlama stillerinden ilham alan kontrol akışı.
Bir Prolog programında kontrol akışını kurcalama yeteneği bir eksikliktir,
mantığın önemli avantajlarından birine doğrudan zarar verdiği için
programlama—programların çözümlerin nasıl bulunacağını belirtmediği.
Bunun yerine, sadece çözümün nasıl görünmesi gerektiğini belirtirler. Bu tasarım
programların yazılmasını ve okunmasını kolaylaştırır. Onlar dağınık değil
çözümlerin nasıl belirleneceği ve özellikle
Çözümü üretmek için hesaplamaların yapıldığı kesin sıra. Böyle,
Mantıksal programlama kontrol akış yönü gerektirmezken, Prolog programları
çoğunlukla verimlilik adına bunları sıklıkla kullanın.

Sayfa 775
754
Bölüm 16 Mantık Programlama Dilleri
16.7.2 Kapalı Dünya Varsayımı
Prolog'un kararının doğası bazen yanıltıcı sonuçlar doğurur. bu
Prolog söz konusu olduğunda, yalnızca gerçekler, onun kullanılarak kanıtlanabilenlerdir.
veri tabanı. Veritabanından başka dünya hakkında hiçbir bilgisi yoktur. Ne zaman
sistem bir sorgu alır ve veri tabanı bunu kanıtlayacak bilgiye sahip değildir.
sorgu kesinlikle, sorgunun yanlış olduğu varsayılır. Prolog, belirli bir
hedef doğrudur, ancak belirli bir hedefin yanlış olduğunu kanıtlayamaz. Basitçe varsayar ki,
bir hedefin doğruluğunu kanıtlayamayacağı için, hedef yanlış olmalıdır. Özünde, Prolog
doğru/yanlış bir sistemden ziyade doğru/başarısız bir sistemdir.
Aslında kapalı dünya varsayımı size hiç de yabancı olmamalı—
yargı sistemimiz de aynı şekilde işliyor. Kanıtlanana kadar şüpheliler masumdur
suçlu. Suçsuz olduklarını kanıtlamak zorunda değiller. Bir dava bir kişiyi kanıtlayamazsa
suçlu ise masum sayılır.
Kapalı dünya varsayımı sorunu, olumsuzlama ile ilgilidir.
Aşağıdaki alt bölümde tartışılan sorun.
16.7.3 Olumsuzlama Problemi
Prolog ile ilgili diğer bir sorun, olumsuzlamanın zorluğudur. Aşağıdakileri göz önünde bulundurun-
iki gerçek ve bir ilişkinin veri tabanı:
ebeveyn(fatura, jake).
ebeveyn(fatura, shelley).
kardeş(X, Y) :- (ebeveyn(M, X), ebeveyn(M, Y).
Şimdi, sorguyu yazdığımızı varsayalım.
kardeş(X, Y).
Prolog ile yanıt verecek
X = jake
Y = jake
Böylece Prolog “düşünür” Jake bir olan kardeş kendini. Bu olur çünkü
Sistem ilk başlatır M ile fatura ve X ile Jake ilk yapmak
alt hedef, ebeveyn(M, X) , doğru. Daha sonra veritabanının başında başlar
ikinci alt hedefle, parent(M, Y) eşleşmesi için tekrar
ait tiations M ile fatura ve Y ile Jake . Çünkü iki alt hedef tatmin edicidir.
her iki eşleşme de veritabanının başlangıcından başlayarak bağımsız olarak yürütülür,
gösterilen yanıt görünür. Bu sonuçtan kaçınmak için X , a olarak belirtilmelidir.
kardeş arasında Y aynı sahipseniz veliler ve onlar aynı değildir.
Ne yazık ki, Prolog'da eşit olmadıklarını söylemek kolay değil,
olarak tartışacağız. En titiz yöntem için bir gerçek eklemeyi gerektirecektir.
her atom çifti, aynı olmadıklarını belirterek. Bu, elbette,
veritabanının çok büyük olmasına neden olur, çünkü genellikle çok daha fazla olumsuzluk vardır.

Sayfa 776
16.7 Prolog 755'in Eksiklikleri
pozitif bilgiden daha fazla bilgidir. Örneğin, çoğu insan 364
sahip oldukları doğum günlerinden daha fazla doğum günü olmayanlar.
Basit bir alternatif çözüm, hedefte X'in olmaması gerektiğini belirtmektir.
Y ile aynı , olduğu gibi
kardeş(X, Y) :- ebeveyn(M, X), ebeveyn(M, Y), değil(X = Y).
Diğer durumlarda, çözüm o kadar basit değildir.
Çözünürlük sağlanamıyorsa, Prolog not operatörü bu durumda tatmin olur.
X = Y alt hedefini belirleyin . Bu nedenle, değil başarılı, değil mutlaka yapar
X'in Y'ye eşit olmadığı anlamına gelir ; daha ziyade, çözünürlüğün kanıtlayamayacağı anlamına gelir
veritabanından X , Y ile aynıdır . Bu nedenle, Prolog değil operatörü
mantıksal bir NOT operatörüne eşdeğerdir; burada NOT, işlenen anlamına gelir.
kanıtlanabilir doğrudur. Bu eşdeğersizlik, eğer olursak bir soruna yol açabilir.
formun bir amacı var
değil(değil(bazı_hedef))).
hangi eşdeğer olurdu
bazı_hedef.
Prolog'un not operatörü gerçek bir mantıksal NOT operatörü olsaydı . Bazı durumlarda,
ancak, aynı değiller. Örneğin, üye kurallarını tekrar düşünün :
üye(Öğe, [Öğe | _]) :- !.
üye(Öğe, [_ | Liste]) :- üye(Öğe, Liste).
Belirli bir listenin öğelerinden birini keşfetmek için hedefi kullanabiliriz.
üye(X, [mary, fred, barb]).
bu, X'in mary ile somutlaştırılmasına neden olur , bu durumda
basılmış. Ama eğer kullandıysak
değil(değil(üye(X, [mary, fred, barb]))).
aşağıdaki olaylar dizisi gerçekleşecektir: İlk olarak, içsel amaç,
başlatmasını, başarılı X için mary . Ardından, Prolog,
sıradaki hedef:
değil(üye(X, [mary, fred, barb])).
Üye başarılı olduğu için bu ifade başarısız olur . Bu hedef başarısız olduğunda,
Prolog her zaman tüm değişkenleri ilksizleştirdiği için X başlatılmamış olur
başarısız olan tüm hedeflerde. Daha sonra, Prolog amacı değil , dış amacı tatmin etmeye çalışacaktı.

Sayfa 777
756
Bölüm 16 Mantık Programlama Dilleri
Bu başarılı olacaktı, çünkü argümanı başarısız olmuştu. Son olarak, sonuç, hangi
olduğu X , yazdırılır. Ancak X şu anda somutlaştırılmayacaktır, bu nedenle sistem
bunu belirtecekti. Genellikle, başlatılmamış değişkenler biçimde yazdırılır
önünde bir alt çizgi bulunan bir rakam dizisi. Yani, Prolog olmasına ne demeli değil ise
mantıksal bir DEĞİL'e eşdeğer olmayan, en azından yanıltıcı olabilir.
Mantıksal DEĞİL'in ayrılmaz bir parçası olamamasının temel nedeni
Prolog, Horn yan tümcesinin biçimidir:
A : - B 1 x B 2 x . . . x B , n
Tüm B önermeleri doğruysa, A'nın doğru olduğu sonucuna varılabilir . Ama saygı-
daha az herhangi birini veya tümünü gerçeğinin ya yalancılığın B ‘s, bu sonucuna edilemez
A yanlıştır. Pozitif mantıktan sadece pozitif mantık sonucuna varılabilir. Böylece
Horn yan tümce formunun kullanılması, herhangi bir olumsuz sonucu engeller.
16.7.4 İç Kısıtlamalar
Bölüm 16.4'te belirtildiği gibi, mantıksal programlamanın temel bir amacı,
vide prosedürel olmayan programlama; yani, programcıların kullandığı bir sistem
Bir programın ne yapması gerektiğini belirtin, ancak bunun nasıl olacağını belirtmenize gerek yok
başardı. Orada sıralama için verilen örnek burada yeniden yazılmıştır:
Sıralama ( old_list, new_list ) permute ( old_list, new_list ) x sıralanmış ( new_list )
( liste ) 5j 1 … j 6 n, liste( j) … liste( j + 1) olacak şekilde sıralanır
Bunu Prolog'da yazmak kolaydır. Örneğin, sıralanmış alt hedef
olarak ifade edilebilir
sıralanır ([]).
sıralanır ([x]).
sıralı ([x, y | liste]) :- x <= y, sıralı ([y | liste]).
Bu sıralama işlemindeki sorun, nasıl sıralanacağı hakkında hiçbir fikrinin olmamasıdır.
gerçekleşene kadar verilen listenin tüm permütasyonlarını numaralandırmaktan
listeyi sıralı olarak içereni yaratın - gerçekten de çok yavaş bir süreç.
Şimdiye kadar hiç kimse, sıralı bir tanımın tanımlandığı bir süreç keşfetmedi.
liste, sıralama için bazı verimli algoritmalara dönüştürülebilir. Çözünürlük
birçok ilginç şey yapabilir, ama kesinlikle bu değil. Bu nedenle, bir Prolog
Bir listeyi sıralayan program, bu sıralamanın nasıl olabileceğinin ayrıntılarını belirtmelidir.
zorunluluk veya işlevsel bir dilde olduğu gibi yapılır.
Tüm bu problemler, mantıksal programlamanın terk edilmesi gerektiği anlamına mı geliyor?
bitti mi? Kesinlikle hayır! Olduğu gibi, birçok yararlı uygulama ile başa çıkma yeteneğine sahiptir.
katyonlar. Ayrıca, ilgi çekici bir konsepte dayanmaktadır ve bu nedenle
başlı başına ilginç. Son olarak, yeni çıkarsama olasılığı vardır.
mantıksal programlama diline olanak sağlayacak teknikler geliştirilecektir.
sistem giderek daha büyük problem sınıflarıyla verimli bir şekilde başa çıkmak için.

Sayfa 778
16.8 Mantık Programlama Uygulamaları 757
16.8 Mantık PROGRAMLAM Uygulamaları g
Bu bölümde, şimdiki zamanın daha büyük sınıflarından birkaçını kısaca tanımlayacağız ve
genel olarak mantık programlamanın potansiyel uygulamaları ve özel olarak Prolog.
16.8.1 İlişkisel Veritabanı Yönetim Sistemleri
İlişkisel veritabanı yönetim sistemleri (RDBMS'ler) verileri şu şekilde depolar:
tablolar. Bu tür veritabanlarındaki sorgular genellikle Yapılandırılmış Sorgu Dili'nde belirtilir.
(SQL). SQL, mantıksal programlamanın non-procedural olduğu anlamda prosedürel değildir.
prosedürel. Kullanıcı, cevabın nasıl alınacağını açıklamaz; daha doğrusu o
ya da sadece cevabın özelliklerini anlatıyor. arasındaki bağlantı
mantıksal programlama ve RDBMS'ler açık olmalıdır. Basit bilgi tabloları
Prolog yapıları ve tablolar arasındaki ilişkiler ile tanımlanabilir.
Prolog kuralları ile uygun ve kolay bir şekilde tanımlanabilir. geri alma süreci
çözümleme işleminin doğasında vardır. Prolog'un hedef ifadeleri şunları sağlar:
RDBMS için sorgular. Mantıksal programlama bu nedenle doğal bir eşleşmedir.
Bir RDBMS uygulama ihtiyaçları.
Uygulamak için mantıksal programlama kullanmanın avantajlarından biri
RDBMS, yalnızca tek bir dilin gerekli olmasıdır. Tipik bir RDBMS'de, bir
veritabanı dili, veri tanımları, veri işleme,
ve tümü genel amaçlı bir programlama lan-
COBOL gibi. Genel amaçlı dil işleme için kullanılır
veri ve giriş ve çıkış fonksiyonları. Bu işlevlerin tümü şurada yapılabilir:
bir mantık programlama dili.
Uygulamak için mantıksal programlama kullanmanın bir başka avantajı
RDBMS, tümdengelim yeteneğinin yerleşik olmasıdır. Geleneksel RDBMS'ler şunları yapabilir:
bir veritabanından açıkça depolanandan başka bir şey çıkarmayın
onlara. Gerçekler ve çıkarım kurallarından ziyade yalnızca gerçekleri içerirler . bu
bir RDBMS için mantıksal programlama kullanmanın birincil dezavantajı, karşılaştırıldığında
geleneksel bir RDBMS ile, mantık programlama uygulamasının
daha yavaştır. Mantıksal çıkarımlar, sıradan tablo aramalarından daha uzun sürer
zorunlu programlama tekniklerini kullanan yöntemler.
16.8.2 Uzman Sistemler
Uzman sistemler, insan uzmanlığını taklit etmek için tasarlanmış bilgisayar sistemleridir.
belirli bir etki alanı. Gerçeklerden oluşan bir veri tabanından, bir çıkarım pro-
cess, etki alanı hakkında bazı buluşsal yöntemler ve bazı dostça insan arabirimi
sistemin uzman bir insan danışman gibi görünmesini sağlar. Ek olarak
bir insan uzman, uzman tarafından sağlanan ilk bilgi tabanına
sistemler kullanım sürecinden öğrenirler, bu nedenle veritabanları yeterli olmalıdır.
dinamik olarak büyümek. Ayrıca, bir uzman sistem yeteneği içermelidir.
olduğunu belirlediğinde ek bilgi almak için kullanıcıyı sorgulamak
bu tür bilgilere ihtiyaç var.

Sayfa 779
758
Bölüm 16 Mantık Programlama Dilleri
Bir uzman sistem tasarımcısı için temel sorunlardan biri,
veritabanının kaçınılmaz tutarsızlıkları ve eksikliği ile. Mantık
programlama bu problemlerle başa çıkmak için çok uygun görünmektedir. Sınav için-
ple, varsayılan çıkarım kuralları, eksiklik sorununun üstesinden gelmeye yardımcı olabilir.
Prolog, uzman sistemler oluşturmak için kullanılabilir ve kullanılmıştır. Kolayca yapabilir
Çözümlemeyi sorgulamanın temeli olarak kullanarak, uzman sistemlerin temel ihtiyaçlarını karşılayın
işleme, öğrenme kapasitesi sağlamak için gerçekleri ve kuralları ekleme yeteneğini kullanarak
ve kullanıcıyı arkasındaki “akıl yürütme” konusunda bilgilendirmek için izleme olanağını kullanmak
verilen bir sonuç. Prolog'da eksik olan, sistemin otomatik olarak
gerektiğinde ek bilgi için kullanıcıyı sorgulayın.
Uzman sistemlerde mantıksal programlamanın en yaygın olarak bilinen kullanımlarından biri
tanımlanan, APES olarak bilinen uzman sistem yapım sistemidir.
Sergot (1983) ve Hammond'da (1983). APES sistemi çok içerir
uzman sistem sırasında kullanıcıdan bilgi toplamak için esnek tesis
yapı. Ayrıca açıklamalar üretmek için ikinci bir tercüman içerir
sorularına verdiği yanıtlara.
APES, aşağıdakiler de dahil olmak üzere birkaç uzman sistem üretmek için başarıyla kullanılmıştır:
biri hükümetin sosyal yardım programının kuralları için, diğeri
İngiliz yasalarının kesin kaynağı olan İngiliz Vatandaşlık Yasası
vatandaşlık.
16.8.3 Doğal Dilde İşleme
Bazı doğal dil işleme türleri mantık programıyla yapılabilir.
ming. Özellikle, bilgisayar yazılım sistemlerine doğal dil arayüzleri,
Akıllı veri tabanları ve diğer akıllı bilgi tabanlı sistemler gibi
mantık programlama ile rahatlıkla yapılabilir. Dil sözdizimini tanımlamak için,
mantıksal programlama biçimlerinin bağlamsız programlamaya eşdeğer olduğu bulunmuştur.
gramer. Mantıksal programlama sistemlerinde ispat prosedürlerinin
belirli ayrıştırma stratejilerine eşdeğer olabilir. Aslında, geriye doğru zincirleme çözüm
tion, yapıları tarafından tanımlanan cümleleri ayrıştırmak için doğrudan kullanılabilir.
bağlamdan bağımsız gramerler. Ayrıca bazı anlambilim türlerinin
dilleri mantıkla modelleyerek doğal dillerin açıklığa kavuşturulabilir.
programlama. Özellikle, mantık tabanlı anlambilim ağlarındaki araştırmalar,
doğal dillerdeki tümce kümelerinin yan tümcelerle ifade edilebileceği gösterilmiştir.
(Deliyanni ve Kowalski, 1979). Kowalski (1979) ayrıca mantık-
tabanlı anlamsal ağlar.
ÖZET
Sembolik mantık, mantık programlaması ve mantık programlaması için temel sağlar.
ming dilleri. Mantıksal programlamanın yaklaşımı veritabanı olarak kullanmaktır.
gerçekler arasındaki ilişkileri belirten ve kullanmak için gerçekler ve kurallar topluluğu
yeni önermelerin geçerliliğini kontrol etmek için otomatik bir çıkarım süreci,

Sayfa 780
Soruları gözden geçirin 759
veri tabanının gerçeklerinin ve kurallarının doğru olduğunu varsayarsak. Bu yaklaşım tek
otomatik teorem ispatı için geliştirilmiştir.
Prolog, en yaygın olarak kullanılan mantık programlama dilidir. kökenler
Mantıksal programlamanın temeli, Robinson'ın çözümleme kuralı geliştirmesinde yatmaktadır.
mantıksal çıkarım. Prolog, öncelikle Colmeraur ve Roussel tarafından geliştirilmiştir.
Marsilya'da, Edinburgh'daki Kowalski'nin yardımıyla.
Mantık programları prosedürel değildir, bu da şu anlama gelir:
çözüm verilir, ancak çözüme ulaşma sürecinin tamamı verilmez.
Prolog ifadeleri gerçekler, kurallar veya hedeflerdir. Çoğu yapılardan oluşur,
aritmetik ifadeler olmasına rağmen, atomik önermeler ve mantık operatörleridir.
siyonlara da izin verilir.
Çözünürlük, bir Prolog yorumlayıcısının birincil etkinliğidir. Bu süreç,
Geri izlemeyi yoğun bir şekilde kullanan, esas olarak aşağıdakiler arasında örüntü eşleştirmeyi içerir.
önermeler. Değişkenler söz konusu olduğunda, değerlere örneklenebilirler.
maçlar sağlamak. Bu somutlaştırma işlemine birleştirme denir .
Mantıksal programlamanın mevcut durumuyla ilgili bir takım sorunlar vardır.
Verimlilik nedenleriyle ve hatta sonsuz döngülerden kaçınmak için programcılar,
bazen programlarında kontrol akışı bilgilerini belirtirler. Ayrıca, orada
kapalı dünya varsayım ve olumsuzlama sorunları.
Mantıksal programlama, başta
ilişkisel veritabanı sistemlerinde, uzman sistemlerde ve doğal dil işlemede.
KAYNAKÇA NOTLAR
Prolog dili birkaç kitapta açıklanmıştır. Edinburgh'un formu
Dil Clocksin ve Mellish'te (2003) ele alınmıştır. Mikrobilgisayar uygulaması-
açıklama Clark ve McCabe'de (1984) anlatılmıştır.
Hogger (1991), mantık programlamanın genel alanı üzerine mükemmel bir kitaptır.
Bu bölümün mantıksal programlama bölümündeki materyalin kaynağıdır.
uygulamalar.
İNCELEME SORULARI
1. Biçimsel mantıkta sembolik mantığın üç temel kullanımı nelerdir?
2. Bir bileşik terimin iki kısmı nelerdir?
3. Bir önermenin ifade edilebileceği iki kip nelerdir?
4. Cümle biçiminde bir önermenin genel biçimi nedir?
5. Öncüller nelerdir? Sonuçlar?
Genel (titiz değil) tanımlarını verin 6. çözünürlük ve birleşme .
7. Horn cümlelerinin biçimleri nelerdir?

Sayfa 781
760
Bölüm 16 Mantık Programlama Dilleri
8. Bildirimsel anlambilimin temel kavramı nedir?
9. Bir dilin prosedürel olmaması ne anlama gelir?
10. Bir Prolog teriminin üç biçimi nelerdir?
11. Örneklenmemiş değişken nedir?
12. Olgu ve kural ifadelerinin sözdizimsel biçimleri ve kullanımları nelerdir?
Prolog?
13. Bağlaç nedir?
14. Bir veri tabanındaki gerçeklerle hedefleri eşleştirmeye yönelik iki yaklaşımı açıklayın.
15. Derinlik öncelikli ve genişlik öncelikli arama arasındaki farkı açıklayın
birden fazla hedefin nasıl karşılandığını tartışırken.
16. Prolog'da geri izlemenin nasıl çalıştığını açıklayın.
17. Prolog deyimi K is K + 1'de neyin yanlış olduğunu açıklayın .
18. Bir Prolog programcısının aşağıdakilerin sırasını kontrol etmesinin iki yolu nelerdir?
çözünürlük sırasında desen eşleştirme?
19. Prolog'da oluştur ve test et programlama stratejisini açıklayın.
20. Prolog tarafından kullanılan kapalı dünya varsayımını açıklayın. bu neden bir
sınırlama?
21. Prolog ile olumsuzlama problemini açıklayın. Bu neden bir sınırlamadır?
22. Otomatik teorem ispatı ile Prolog's arasındaki bağlantıyı açıklayın.
çıkarım süreci.
23. Prosedürel ve prosedürel olmayan diller arasındaki farkı açıklayın.
24. Prolog sistemlerinin neden geri izleme yapması gerektiğini açıklayın.
25. Prolog'da çözümleme ve birleştirme arasındaki ilişki nedir?
PROBLEM SETİ
1. Ada'da veri yazma kavramını Prolog'unkiyle karşılaştırın.
2. Uygulamak için çok işlemcili bir makinenin nasıl kullanılabileceğini açıklayın
çözüm. Prolog, şu anda tanımlandığı gibi bu yöntemi kullanabilir mi?
3. Soy ağacınızın bir Prolog tanımını yazın (yalnızca gerçeklere dayalı olarak),
büyükanne ve büyükbabanıza geri dönmek ve tüm torunlar dahil. Emin ol
tüm ilişkileri içermek.
4. Tüm ilişkiler de dahil olmak üzere aile ilişkileri için bir dizi kural yazın
büyükanne ve büyükbabalardan iki nesil boyunca. Şimdi bunları gerçeklere ekleyin
Problem 3'ü seçin ve mümkün olduğu kadar çok gerçeği ortadan kaldırın.

Sayfa 782
Programlama Alıştırmaları 761
5. Aşağıdaki İngilizce şartlı ifadeleri Prolog başlıklı olarak yazınız.
Korna cümleleri:
a. Fred, Mike'ın babasıysa, o zaman Fred bir atadır.
Mike tor.
B. Mike Joe'nun babasıysa ve Mike babasıysa
Mary, o zaman Mary, Joe'nun kız kardeşidir.
C. Mike, Fred'in kardeşiyse ve Fred de
Mary'nin babası, o zaman Mike, Mary'nin amcasıdır.
6. Scheme'in liste işleme yeteneklerinin iki şekilde açıklanması ve
Prolog benzer.
7. Scheme ve Prolog'un liste işleme yetenekleri ne şekildedir?
farklı?
8. Prolog ile ML'nin iki benzerlik ve
iki fark.
9. Bir Prolog kitabından, bir olayın tanımını öğrenin ve yazın.
kontrol sorunu. Prolog neden bu sorunun kendi sisteminde var olmasına izin veriyor?
uygulama?
10. Skolem normal formu hakkında iyi bir bilgi kaynağı bulun ve bir
kısa ama net açıklama.
PROGRAMLAMAALIŞTIRMALAR
1. parent(X, Y) , male(X) ve Female(X) yapılarını kullanarak yazın
mom(X, Y) tanımlayan bir yapı .
2. parent(X, Y) , male(X) ve Female(X) yapılarını kullanarak yazın
sister(X, Y) tanımlayan bir yapı .
3. Bir sayı listesinin maksimumunu bulan bir Prolog programı yazın.
4. Verilen iki listenin kesişiminde başarılı olan bir Prolog programı yazınız.
parametreler boş.
5. Aşağıdakilerin birleşimini içeren bir liste döndüren bir Prolog programı yazın.
verilen iki listenin öğeleri.
6. Belirli bir listenin son öğesini döndüren bir Prolog programı yazın.
7. Hızlı sıralama uygulayan bir Prolog programı yazın.

Sayfa 783
Bu sayfa bilerek boş bırakılmıştır

Sayfa 784
763
ACM. (1979) “Bölüm A: Ön Ada Referans Kılavuzu” ve “Kısım B: Tasarımın Gerekçesi
Ada Programlama Dili'nin. SIGPLAN Bildirimleri, Cilt. 14, No. 6.
ACM. (1993a) Programlama Dili Konferans Tutanakları Tarihi. ACM SİGPLANI
Bildirimler, Cilt. 28, No. 3, Mart.
ACM. (1993b) "Yüksek Performanslı FORTRAN Dil Belirtimi Bölüm 1." FORTRAN Forumu,
Cilt 12, No. 4.
Aho, AV, MS Lam, R. Sethi ve JD Ullman. (2006) Derleyiciler: İlkeler, Teknikler ve
Araçlar. 2e, Addison-Wesley, Reading, MA.
Aho, AV, BW Kernighan ve PJ Weinberger. (1988) AWK Programlama Dili.
Addison-Wesley, Okuma, MA.
Andrews, GR ve FB Schneider. (1983) "Eşzamanlı Programlama için Kavramlar ve Gösterimler."
ACM Bilgi İşlem Anketleri, Cilt. 15, No. 1, s. 3-43.
ANSI. (1966) Amerikan Ulusal Standart Programlama Dili FORTRAN. Amerikan Ulusal
Standartlar Enstitüsü, New York.
ANSI. (1976) Amerikan Ulusal Standart Programlama Dili PL/I. ANSI X3.53–1976.
Amerikan Ulusal Standartlar Enstitüsü, New York.
ANSI. (1978a) Amerikan Ulusal Standart Programlama Dili FORTRAN. ANSI X3.9–1978.
Amerikan Ulusal Standartlar Enstitüsü, New York.
ANSI. (1978b) Amerikan Ulusal Standart Programlama Dili Minimal BASIC. ANSI
X3. 60–1978. Amerikan Ulusal Standartlar Enstitüsü, New York.
ANSI. (1985) Amerikan Ulusal Standart Programlama Dili COBOL. ANSI X3.23–1985.
Amerikan Ulusal Standartlar Enstitüsü, New York.
ANSI. (1989) Amerikan Ulusal Standart Programlama Dili C. ANSI X3.159–1989.
Amerikan Ulusal Standartlar Enstitüsü, New York.
ANSI. (1992) Amerikan Ulusal Standart Programlama Dili FORTRAN 90. ANSI X3. 198–
1992. Amerikan Ulusal Standartlar Enstitüsü, New York.
Arden, BW, BA Galler ve RM Graham. (1961) "Michigan'da MAD." Datamation, Cilt. 7, Hayır.
12, s. 27–28.
KOL. (1995) Ada Referans Kılavuzu. ISO/IEC/ANSI 8652:19. Intermetrics, Cambridge, MA.
Arnold, K., J. Gosling ve D. Holmes (2006) The Java (TM) Programlama Dili, 4e. Addison-
Wesley, Okuma, MA.
Backus, J. (1954) “IBM 701 Hız Kodlama Sistemi.” J. ACM, Cilt. 1, s. 4–6.
Backus, J. (1959) “Önerilen Uluslararası Cebirsel Dilin Sözdizimi ve Anlambilimi
Zürih ACM-GAMM Konferansı. Bildiriler Uluslararası Bilgi Konferansı
İşleme. UNESCO, Paris, s. 125–132.
Backus, J. (1978) “Programlama von Neumann Tarzından Kurtulabilir mi? Fonksiyonel
Stil ve Program Cebiri. Komün. ACM, Cilt. 21, No. 8, s. 613-641.
bibliyografya

Sayfa 785
764
bibliyografya
Backus, J., FL Bauer, J. Green, C. Katz, J. McCarthy, P. Naur, AJ Perlis, H. Rutishauser, K. Samelson,
B. Vauquois, JH Wegstein, A. van Wijngaarden ve M. Woodger. (1963) “Gözden Geçirilmiş Rapor
Algoritmik Dil ALGOL 60.” Komün. ACM, Cilt. 6, No. 1, s. 1-17.
Balena, F. (2003) Programlama Microsoft Visual Basic .NET Sürüm 2003, Microsoft Press,
Redmond, WA.
Ben-Ari, M. (1982) Eşzamanlı Programlamanın İlkeleri. Prentice-Hall, Englewood Cliffs, NJ.
Birtwistle, GM, O.-J. Dahl, B. Myhrhaug ve K. Nygaard. (1973) Simula BAŞLIYOR. Van Nostrand
Reinhold, New York.
Bodwin, JM, L. Bradley, K. Kanda, D. Litle ve UF Pleban. (1982) “Bir
Denotational Semantics'e Dayalı Deneysel Derleyici Oluşturucu. ACM SİGPLANI
Bildirimler, Cilt. 17, No. 6, s. 216–229.
Bohm, C. ve G. Jacopini. (1966) “Akış Diyagramları, Turing Makineleri ve Yalnızca
İki Oluşum Kuralı.” Komün. ACM, Cilt. 9, No. 5, s. 366-371.
Bolsky, M. ve D. Korn. (1995) Yeni KornShell Komut ve Programlama Dili.
Prentice-Hall, Englewood Cliffs, NJ.
Booch, G. (1987) Yazılım Mühendisliği ile Ada, 2e. Benjamin/Cummings, Redwood City, CA.
Bradley, JC (1989) Modüler Yapıları Kullanan QuickBASIC ve QBASIC. WC Brown, Dubuque, IA.
Brinch Hansen, P. (1973) İşletim Sistemi İlkeleri. Prentice-Hall, Englewood Cliffs, NJ.
Brinch Hansen, P. (1975) “Eşzamanlı Programlama Dili-Pascal.” IEEE İşlemleri
Yazılım Mühendisliği üzerine, Cilt. 1, No. 2, s. 199–207.
Brinch Hansen, P. (1977) Eşzamanlı Programların Mimarisi. Prentice Salonu, Englewood
Cliffs, NJ.
Brinch Hansen, P. (1978) “Dağıtılmış Süreçler: Eş Zamanlı Bir Programlama Kavramı.” Komün.
ACM, Cilt. 21, No. 11, s. 934-941.
Brown, JA, S. Pakin ve RP Polivka. (1988) Bir Bakışta APL2. Prentice Salonu, Englewood
Cliffs, NJ.
Campione, M., K. Walrath ve A. Huml. (2001) Java Eğitimi, 3e. Addison-Wesley, Okuma,
MA.
Cardelli, L., J. Donahue, L. Glassman, M. Jordan, B. Kalsow ve G. Nelson. (1989) Modül-3
Rapor (gözden geçirildi). Dijital Sistem Araştırma Merkezi, Palo Alto, CA.
Chambers, C. ve D. Ungar. (1991) “Saf Nesne Yönelimli Dilleri Pratik Hale Getirmek.” SIGPLAN
Bildirimler, Cilt. 26, No. 1, s. 1–15.
Chomsky, N. (1956) “Dilin Tanımlanması için Üç Model.” IRE İşlemleri
Bilgi Teorisi, Cilt. 2, No. 3, s. 113–124.
Chomsky, N. (1959) “Gramerlerin Belirli Biçimsel Özellikleri Üzerine.” Bilgi ve Kontrol,
Cilt 2, No. 2, s. 137–167.
Church, A. (1941) Annals of Mathematics Studies. Cilt 6: Lambda Dönüşüm Hesapları.
Princeton Üniv. Basın, Princeton, NJ. Klaus Reprint Corporation, New York tarafından yeniden basılmıştır,
1965.
Clark, KL ve FG McCabe. (1984) Mikro-PROLOG: Mantıkta Programlama. çırak-salon,
Englewood Kayalıkları, NJ.
Clarke, LA, JC Wileden ve AL Wolf. (1980) “Ada'da Yuva Yapmak Kuşlar İçindir.” ACM SİGPLANI
Bildirimler, Cilt. 15, No. 11, s. 139–145.
Cleaveland, JC (1986) Veri Türlerine Giriş. Addison-Wesley, Okuma, MA.
Cleaveland, JC ve RC Uzgalis. (1976) Programlama Dilleri için Gramerler: Ne Her
Programcı Dil Bilgisini Bilmelidir. Amerikan Elsevier, New York.
Clocksin, WF ve CS Mellish. (2003) Prolog'da Programlama, 5e. Springer-Verlag, New York.
Cohen, J. (1981) “Bağlantılı Veri Yapılarının Çöp Toplanması.” ACM Hesaplama Anketleri,
Cilt 13, No. 3, s. 341–368.
Converse, T. ve J. Park. (2000) PHP 4 İncil. IDG Kitapları, New York.
Conway, ME (1963). “Ayrılabilir Geçiş Diyagramı Derleyicisinin Tasarımı.” Komün. ACM,
Cilt 6, No. 7, s. 396–408.
Conway, R. ve R. Constable. (1976) “PL/CS—PL/I'nin Disiplinli Bir Alt Kümesi.” Teknik rapor
TR76/293. Bilgisayar Bilimleri Bölümü, Cornell Üniversitesi, Ithaca, NY.
Cornell Üniversitesi. (1977) PL/C Kullanıcı Kılavuzu, Sürüm 7.6. Bilgisayar Bilimleri Bölümü,
Cornell Üniversitesi, Ithaca, NY.

Sayfa 786
Kaynakça 765
Correa, N. (1992) “Boş Kategoriler, Zincir Bağlama ve Ayrıştırma.” s. 83–121, İlke Tabanlı
Ayrıştırma. Ed. RC Berwick, SP Abney ve C. Tenny. Kluwer Akademik Yayıncılar, Boston.
Cousineau, G., M.Mauny ve K. Callaway. (1998) Programlamaya İşlevsel Yaklaşım.
Cambridge Üniversitesi Yayınları,
Dahl, O.-J., EW Dijkstra ve CAR Hoare. (1972) Yapılandırılmış Programlama. Akademik Basın,
New York.
Dahl, O.-J. ve K. Nygaard. (1967) “SIMULA 67 Ortak Temel Önerisi.” norveçce bilgisayar
Merkezi Belge, Oslo.
Deitel, HM, DJ Deitel ve TR Nieto. (2002) Visual BASIC .Net: Nasıl Programlanır, 2e.
Prentice-Hall, Inc. Upper Saddle River, NJ.
Deliyanni, A. ve RA Kowalski. (1979) “Mantık ve Semantik Ağlar.” Komün. ACM,
Cilt 22, No. 3, s. 184-192.
Savunma Bakanlığı. (1960) “COBOL, Ortak İş Odaklı için İlk Spesifikasyonlar
Dilim." ABD Savunma Bakanlığı, Washington, DC
Savunma Bakanlığı. (1961) “COBOL—1961, Ortak Bir İşletme için Gözden Geçirilmiş Spesifikasyonlar
Yönlendirilmiş Dil.” ABD Savunma Bakanlığı, Washington, DC
Savunma Bakanlığı. (1962) “COBOL—1961 GENİŞLETİLMİŞ, Ortak Kullanım için Genişletilmiş Spesifikasyonlar
İş Odaklı Dil.” ABD Savunma Bakanlığı, Washington, DC
Savunma Bakanlığı. (1975a) “Yüksek Dereceli Programlama Dilleri için Gereksinimler,
SAMAN ADAM." Temmuz. ABD Savunma Bakanlığı, Washington, DC
Savunma Bakanlığı. (1975b) “Yüksek Dereceli Programlama Dilleri İçin Gereksinimler,
AHŞAP ADAM.” Ağustos. ABD Savunma Bakanlığı, Washington, DC
Savunma Bakanlığı. (1976) “Yüksek Dereceli Programlama Dilleri için Gereksinimler, TINMAN.”
Haziran. ABD Savunma Bakanlığı, Washington, DC
Savunma Bakanlığı. (1977) “Yüksek Dereceli Programlama Dilleri için Gereksinimler, IRONMAN.”
Ocak ayı. ABD Savunma Bakanlığı, Washington, DC
Savunma Bakanlığı. (1978) “Yüksek Dereceli Programlama Dilleri için Gereksinimler,
STEELMAN.” Haziran. ABD Savunma Bakanlığı, Washington, DC
Savunma Bakanlığı. (1980a) “Yüksek Dereceli Programlama Dilleri İçin Gereksinimler,
TAŞ ADAM." Şubat. ABD Savunma Bakanlığı, Washington, DC
Savunma Bakanlığı. (1980b) “Ortak için Programlama Ortamı Gereksinimleri
Yüksek Dereceli Dil, STONEMAN.” ABD Savunma Bakanlığı, Washington, DC
DeRemer, F. (1971) “Basit LR(k) Gramerleri.” Komün. ACM, Cilt. 14, No. 7, s. 453-460.
DeRemer, F. ve T. Pennello. (1982) “LALR(1) İleriye Bakış Kümelerinin Verimli Hesaplanması.” ACM
TOPLAS, Cilt. 4, No. 4, s. 615–649.
Deutsch, LP ve DG Bobrow. (1976) “Etkili Bir Artımlı Otomatik Çöp Toplayıcı.”
Komün. ACM, Cilt. 11, No. 3, s. 522–526.
Dijkstra, EW (1968a) “Zararlı Olarak Kabul Edilen Açıklamaya Git.” Komün. ACM, Cilt. 11, No.3,
s. 147–149.
Dijkstra, EW (1968b) “Ardışık Süreçlerde İşbirliği”. Programlama Dillerinde,
F. Genuys (ed.). Academic Press, New York, s. 43–112.
Dijkstra, EW (1972) “Mütevazı Programcı.” Komün. ACM, Cilt. 15, No. 10, s. 859-866.
Dijkstra, EW (1975) “Korumalı Komutlar, Belirsizlik ve Programların Resmi Türevi.”
Komün. ACM, Cilt. 18, No. 8, s. 453–457.
Dijkstra, EW (1976). Bir Programlama Disiplini. Prentice-Hall, Englewood Cliffs, NJ.
Dybvig, RK (2003) Şema Programlama Dili, 3e. MIT Press, Boston.
Ellis, MA ve B. Stroustrup (1990) The Annotated C++ Reference Manual. Addison-Wesley,
Okuma, MA.
Farber, DJ, RE Griswold ve IP Polonsky. (1964) “SNOBOL, Bir Dizi Manipülasyon Dili.”
J. ACM, Cilt. 11, No. 1, s. 21–30.
Farrow, R. (1982) “LINGUIST 86: Niteliğe Dayalı Bir Başka Çevirmen Yazma Sistemi
Gramerler.” ACM SIGPLAN Bildirimleri, Cilt. 17, No. 6, s. 160-171.
Fischer, CN, GF Johnson, J. Mauney, A. Pal ve DL Stock. (1984) “Poe Dili Temelli
Editör Projesi.” ACM SIGPLAN Bildirimleri, Cilt. 19, No. 5, s. 21–29.
Fischer, CN ve RJ LeBlanc. (1977) “UW-Pascal Referans Kılavuzu.” Madison Akademik
Bilgi İşlem Merkezi, Madison, WI.

Sayfa 787
766
bibliyografya
Fischer, CN ve RJ LeBlanc. (1980) "Pascal'da Çalışma Zamanı Tanılamanın Uygulanması."
Yazılım Mühendisliğinde IEEE İşlemleri, SE-6, No. 4, s. 313–319.
Fischer, CN ve RJ LeBlanc. (1991) C. Benjamin/Cummings, Menlo'da Derleyici Oluşturma
Park, CA.
Flanagan, D. (2002) JavaScript: Kesin Kılavuz, 4e. O'Reilly Medya, Sivastopol, Kaliforniya
Floyd, RW (1967) “Programlara Anlam Atama.” Bildiriler Sempozyumu Uygulamalı Matematik-
matematik. Bilgisayar Biliminin Matematiksel Yönleri Ed. JT Schwartz. Amerikan Matematik
Toplum, Providence, UR.
Frege, G. (1892) “Über Sinn ve Bedeutung.” Felsefe ve Felsefe için Zeitschrift
Kritik, Cilt. 100, s. 25–50.
Friedl, JEF (2006) Normal İfadelerde Ustalaşmak, 3e. O'Reilly Media, Sivastopol, CA.
Friedman, DP ve DS Wise. (1979) “Referans Saymanın Döngüleri Toplama Yeteneği Değildir.
aşılmaz." Bilgi İşlem Mektupları, Cilt. 8, No. 1, s. 41–45.
Fuchi, K. (1981) “Bilgi Bilgi İşleme Sistemlerinin Amaçlanması.” Bildiriler
Beşinci Nesil Bilgi İşlem Sistemleri Uluslararası Konferansı. Japonya Bilgileri
İşlem Geliştirme Merkezi, Tokyo. North-Holland Publishing tarafından yeniden yayınlandı (1982),
Amsterdam.
Gehani, N. (1983) Ada: Gelişmiş Bir Giriş. Prentice-Hall, Englewood Cliffs, NJ.
Gilman, L. ve AJ Rose. (1976) APL: Etkileşimli Bir Yaklaşım, 2e. J. Wiley, New York.
Goldberg, A. ve D. Robson. (1983) Smalltalk-80: Dil ve Uygulanması.
Addison-Wesley, Okuma, MA.
Goldberg, A. ve D. Robson. (1989) Smalltalk-80: Dil. Addison-Wesley, Okuma, MA.
Goodenough, JB (1975) “İstisna İşleme: Sorunlar ve Önerilen Gösterim.” Komün. ACM,
Cilt 18, No. 12, s. 683–696.
Goos, G. ve J. Hartmanis (ed.) (1983) The Programming Language Ada Reference Manual.
Amerikan Ulusal Standartlar Enstitüsü. ANSI/MIL-STD-1815A–1983. Ders Notları
Bilgisayar Bilimi 155. Springer-Verlag, New York.
Gordon, M. (1979) Programlama Dillerinin Düz Anlamlı Tanımı, Bir Giriş.
Springer-Verlag, Berlin-New York.
Graham, P. (1996) ANSI Ortak LISP. Prentice-Hall, Englewood Cliffs, NJ.
Gries, D. (1981) Programlama Bilimi. Springer-Verlag, New York.
Griswold, RE ve MT Griswold. (1983) ICON Programlama Dili. çırak-salon,
Englewood Kayalıkları, NJ.
Griswold, RE, F. Poage ve IP Polonsky. (1971) SNOBOL 4 Programlama Dili, 2e.
Prentice-Hall, Englewood Cliffs, NJ.
Halstead, RH, Jr. (1985) “Multilisp: Eşzamanlı Sembolik Hesaplama için Bir Dil.” ACM
Programlama Dili ve Sistemleri Üzerine İşlemler, Cilt. 7, No. 4, Ekim 1985, s. 501-538.
Hammond, P. (1983) APES: Bir Kullanım Kılavuzu. Bilgisayar Bölümü Raporu 82/9. imparatorluk
Bilim ve Teknoloji Koleji, Londra.
Harbison, SP III ve GL Steele, Jr. (2002) AC Referans Kılavuzu, 5e, Prentice-Hall, Upper
Saddle Nehri, NJ.
Henderson, P. (1980) Fonksiyonel Programlama: Uygulama ve Uygulama. çırak-salon,
Englewood Kayalıkları, NJ.
Hoare, CAR (1969) “Bilgisayar Programlamanın Aksiyomatik Temeli.” Komün. ACM, Cilt. 12,
10, s. 576–580.
Hoare, CAR (1972) "Veri Temsillerinin Doğruluğunun Kanıtı." Acta Informatica, Cilt. 1,
s. 271–281.
Hoare, CAR (1973) “Programlama Dili Tasarımına İlişkin İpuçları.” Bildiriler ACM SIGACT/
SIGPLAN Programlama Dillerinin İlkeleri Konferansı. Teknik olarak da yayınlandı
Rapor STAN-CS-73-403, Stanford Üniversitesi Bilgisayar Bilimleri Bölümü.
Hoare, CAR (1974) “Monitörler: Bir İşletim Sistemi Yapılandırma Kavramı.” Komün. ACM,
Cilt 17, No. 10, s. 549-557.
Hoare, CAR (1978) “Sıralı Süreçleri İletmek.” Komün. ACM, Cilt. 21, No.8,
s. 666-677.
Hoare, CAR (1981) “İmparatorun Eski Giysileri.” Komün. ACM, Cilt. 24, No. 2, s. 75-83.

Sayfa 788
Kaynakça 767
Hoare, CAR ve N. Wirth. (1973) “Programlama Dilinin Aksiyomatik Bir Tanımı
Pascal." Acta Informatica, Cilt. 2, s. 335–355.
Hogger, CJ (1984) Mantık Programlamaya Giriş. Akademik Basın, Londra.
Hogger, CJ (1991) Mantık Programlamanın Temelleri. Oxford Bilim Yayınları, Oxford, İngiltere.
Holt, RC, GS Graham, ED Lazowska ve MA Scott. (1978) Yapılandırılmış Eşzamanlı Pro-
İşletim Sistemleri Uygulamaları ile gramlama. Addison-Wesley, Okuma, MA.
Horn, A. (1951) “Cebirlerin Doğrudan Birleşimleri İçin Doğru Olan Cümleler Üzerine.” J. Sembolik Mantık,
Cilt 16, s. 14–21.
Hudak, P. ve J. Fasel. (1992) “Haskell'e Nazik Bir Giriş, ACM SIGPLAN Notices, 27(5),
Mayıs 1992, s. T1–T53.
Hughes, (1989) “Neden Fonksiyonel Programlama Önemlidir”, The Computer Journal, Cilt. 32, No.2,
s. 98–107.
Huskey, HK, R. Love ve N. Wirth. (1963) “BC NELIAC'ın Sözdizimsel Tanımı.” Komün.
ACM, Cilt. 6, No. 7, s. 367–375.
IBM. (1954) “Ön Rapor, IBM Mathematical FORmula TRANslat- için Spesifikasyonlar-
Sistemi, FORTRAN.” IBM Şirketi, New York.
IBM. (1956) “Programmer's Reference Manual, FORTRAN Otomatik Kodlama Sistemi
IBM 704 EDPM." IBM Şirketi, New York.
IBM. (1964) “Yeni Programlama Dili.” IBM Birleşik Krallık Laboratuvarları.
Ichbiah, JD, JC Heliard, O. Roubine, JGP Barnes, B. Krieg-Brueckner ve BA Wichmann.
(1979) “Ada Programlama Dilinin Tasarımının Gerekçesi.” ACM SİGPLANI
Bildirimler, Cilt. 14, No. 6, Kısım B.
IEEE. (1985) “İkili Kayan Nokta Aritmetiği.” IEEE Standardı 754, IEEE, New York.
Ierusalimschy, R. (2006) Lua'da Programlama, 2e, Lua.org, Rio de Janeiro, Brezilya.
INCITS/ISO/IEC (1997) 1539-1-1997 Bilgi Teknolojisi—Programlama Dilleri—
FORTRAN Bölüm 1: Temel Dil. Amerikan Ulusal Standartlar Enstitüsü, New York.
Ingerman, PZ (1967). “Panini-Backus Formu Önerildi.” Komün. ACM, Cilt. 10, No. 3, s. 137.
İntermetrikler. (1993) Programlama Dili Ada, Taslak, Sürüm 4.0. Cambridge, MA.
ISO. (1982) Programlama Dili Pascal için Spesifikasyon. ISO7185–1982. Uluslararası
Standardizasyon Örgütü, Cenevre, İsviçre.
ISO/IEC (1996) 14977:1996, Bilgi Teknolojisi—Sözdizimsel Metadil—Genişletilmiş BNF.
Uluslararası Standardizasyon Örgütü, Cenevre, İsviçre.
ISO. (1998) ISO14882-1, ISO/IEC Standardı – Bilgi Teknolojisi—Programlama Dili—
C++. Uluslararası Standardizasyon Örgütü, Cenevre, İsviçre.
ISO. (1999) ISO/IEC 9899:1999, Programlama Dili C. Amerikan Ulusal Standartları
Enstitüsü, New York.
ISO/IEC (2002) 1989:2002 Bilgi Teknolojisi—Programlama Dilleri—COBOL. Amerikan
Ulusal Standartlar Enstitüsü, New York.
ISO/IEC (2010) 1539-1 Bilgi Teknolojisi—Programlama Dilleri—Fortran. Amerikan
Ulusal Standartlar Enstitüsü, New York.
Iverson, KE (1962) Bir Programlama Dili. John Wiley, New York.
Jensen, K. ve N. Wirth. (1974) Pascal Kullanıcı Kılavuzu ve Raporu. Springer-Verlag, Berlin.
Johnson, SC (1975) “Yacc—Yine Bir Başka Derleyici Derleyicisi.” Bilgisayar Bilimi Raporu 32.
AT&T Bell Laboratuvarları, Murray Hill, NJ.
Jones, ND (ed.) (1980) Semantik Yönlü Derleyici Üretimi. Bilgisayarda Ders Notları
Bilim, Cilt. 94. Springer-Verlag, Heidelberg, FRG.
Kay, A. (1969) Reaktif Motor. Doktora tezi. Utah Üniversitesi, Eylül.
Kernighan, BW ve DM Ritchie. (1978) C Programlama Dili. Prentice Salonu, Englewood
Cliffs, NJ.
Knuth, DE (1965) “Dillerin Soldan Sağa Çevirisi Üzerine.” Bilgi ve Kontrol,
Cilt 8, No. 6, s. 607–639.
Knuth, DE (1967) “ALGOL 60'ta Kalan Sorun Noktaları.” Komün. ACM, Cilt. 10, Hayır.
10, s. 611–618.
Knuth, DE (1968a) “Bağlamdan Bağımsız Dillerin Anlambilimi.” Matematiksel Sistemler Teorisi,
Cilt 2, No. 2, s. 127–146.

Sayfa 789
768
bibliyografya
Knuth, DE (1968b) Bilgisayar Programlama Sanatı, Cilt. ben, 2e. Addison-Wesley, Okuma, MA.
Knuth, DE (1974) “GOTO İfadeleri ile Yapılandırılmış Programlama.” ACM Hesaplama Anketleri,
Cilt 6, No. 4, s. 261–301.
Knuth, DE (1981) Bilgisayar Programlama Sanatı, Cilt. II, 2e. Addison-Wesley, Okuma, MA.
Knuth, DE ve LT Pardo. (1977) “Programlama Dillerinin Erken Gelişimi.” İçinde
Bilgisayar Bilimi ve Teknolojisi Ansiklopedisi, Cilt. 7. Dekker, New York, s. 419-493.
Kochan, SG (2009) Objective-C 2.0'da Programlama. Addison-Wesley, Upper Saddle River, NJ.
Kowalski, RA (1979) Problem Çözme için Mantık. Yapay Zeka Serisi, Cilt. 7. Elsevier-
Kuzey Hollanda, New York.
Laning, JH, Jr. ve N. Zierler. (1954) “Matematiksel Denklemlerin Çevirisi İçin Bir Program
Fırtına ben." Mühendislik muhtırası E-364. Enstrümantasyon Laboratuvarı, Massachusetts
Teknoloji Enstitüsü, Cambridge, MA.
Ledgard, H. (1984) Amerikan Pascal Standardı. Springer-Verlag, New York.
Ledgard, HF ve M. Marcotty. (1975) "Kontrol Yapılarının Bir Soykütüğü." Komün. ACM,
Cilt 18, No. 11, s. 629-639.
Lischner, R. (2000) Özetle Delphi. O'Reilly Media, Sivastopol, CA.
Liskov, B., RL Atkinson, T. Bloom, JEB Moss, C. Scheffert, R. Scheifler ve A. Snyder (1981)
“CLU Referans Kılavuzu.” Springer, New York.
Liskov, B. ve A. Snyder. (1979) "CLU'da Özel Durum İşleme." Yazılım Üzerinden IEEE İşlemleri
Mühendislik, Cilt. SE-5, No. 6, s. 546–558.
Lomet, D. (1975) “Serbest Depolamaya Yapılan Referansların Geçersizleştirilmesi için Düzen.” IBM J. Araştırma ve
Geliştirme, Cilt. 19, s. 26–35.
Lutz, M. ve D. Ascher. (2004) Python Öğrenme, 2e. O'Reilly Media, Sivastopol, CA.
MacLaren, MD (1977) "PL/I'de İstisna İşleme." ACM SIGPLAN Bildirimleri, Cilt. 12, No.3,
s. 101–104.
Marcotty, M., HF Ledgard ve GV Bochmann. (1976) “Biçimsel Tanımların Bir Örnekleyicisi.”
ACM Bilgi İşlem Anketleri, Cilt. 8, No. 2, s. 191–276.
Mather, DG ve SV Waite (ed.) (1971) BASIC. 6e. New England University Press, Hannover,
NH.
McCarthy, J. (1960) “Sembolik İfadelerin Özyinelemeli İşlevleri ve Bunların Hesaplanması
Makine, Bölüm I.” Komün. ACM, Cilt. 3, No. 4, s. 184–195.
McCarthy, J., PW Abrahams, DJ Edwards, TP Hart ve M. Levin. (1965) LISP 1.5 Programcının
Manuel, 2e. MIT Press, Cambridge, MA.
McCracken, D. (1970) "APL Nereye." Datamation, 15 Eylül, s. 53–57.
Metcalf, M., J. Reid ve M. Cohen. (2004) Fortran 95/2003 Açıklama, 3e. Oxford Üniversitesi
Basın, Oxford, İngiltere.
Meyer, B. (1990) Programlama Dilleri Teorisine Giriş. Prentice Salonu, Englewood
Cliffs, NJ.
Meyer, B. (1992) Eyfel: Dil. Prentice-Hall, Englewood Cliffs, NJ.
Microsoft. (1991) Microsoft Visual Basic Dil Referansı. Belge DB20664-0491,
Redmond, WA.
Milner, R., M. Tofte ve R. Harper. (1990) Standart ML'nin Tanımı. MIT Press, Cambridge,
MA.
Milos, D., U. Pleban ve G. Loegel. (1984) “Derleyici Spesifikasyonlarının Doğrudan Uygulanması.”
ACM Programlama Dilleri İlkeleri 1984, s. 196–202.
Mitchell, JG, W. Maybury ve R. Sweet. (1979) Mesa Dil Kılavuzu, Sürüm 5.0, CSL-79-3.
Xerox Araştırma Merkezi, Palo Alto, CA.
Moss, C. (1994) Prolog++: Nesne Yönelimli ve Mantıksal Programlamanın Gücü. Addison-Wesley,
Okuma, MA.
Moto-oka, T. (1981) “Bilgi Bilgi İşleme Sistemlerinin Mücadelesi.” Bildiriler
Beşinci Nesil Bilgi İşlem Sistemleri Uluslararası Konferansı'ndan. Japonya Bilgileri
İşlem Geliştirme Merkezi, Tokyo. North-Holland Publishing tarafından yeniden yayınlandı (1982),
Amsterdam.
Naur, P. (ed.) (1960) “Algoritmik Dil ALGOL 60 Üzerine Rapor.” Komün. ACM, Cilt. 3,
5, s. 299–314.

Sayfa 790
Kaynakça 769
Newell, A. ve HA Simon. (1956) “Mantık Teorisi Makinesi—Karmaşık Bir Bilgi
İşleme Sistemi.” Bilgi Teorisi Üzerine IRE İşlemleri, Cilt. IT-2, No. 3, s. 61–79.
Newell, A. ve FM Tonge. (1960) “Bilgi İşleme Dili V’ye Giriş.”
Komün. ACM, Cilt. 3, No. 4, s. 205–211.
Nilsson, NJ (1971) Yapay Zekada Problem Çözme Yöntemleri. McGraw-Hill, New York.
Ousterhout, JK (1994) Tcl ve Tk Toolkit. Addison-Wesley, Okuma, MA.
Paepcke, E. (editör). Nesneye Yönelik Programlama: CLOS Perspektifi. MIT Press, 1993.
Pagan, FG (1981) Programlama Dillerinin Biçimsel Özellikleri. Prentice Salonu, Englewood
Cliffs, NJ.
Papert, S. (1980) MindStorms: Çocuklar, Bilgisayarlar ve Güçlü Fikirler. Temel Kitaplar, New York.
Perlis, A. ve K. Samelson. (1958) “Ön Rapor—Uluslararası Cebirsel Dil.”
Komün. ACM, Cilt. 1, No. 12, s. 8–22.
Peyton Jones, SL (1987) Fonksiyonel Programlama Dillerinin Uygulanması. çırak-salon,
Englewood Kayalıkları, NJ.
Pratt, TW (1984) Programlama Dilleri: Tasarım ve Uygulama, 2e. çırak-salon,
Englewood Kayalıkları, NJ.
Pratt, TW ve MV Zelkowitz (2001) Programlama Dilleri: Tasarım ve Uygulama, 4e.
Prentice-Hall, Englewood Cliffs, NJ.
Unix Programlama Raymond E. (2004) Mad. Addison Wesley, Boston.
Remington-Rand. (1952) “UNIVAC Kısa Kodu.” Yayınlanmamış aynı notlar koleksiyonu. önsöz
25 Ekim 1955 tarihli AB Tonik (1 s.); JR Logan tarafından önsöz, tarihsiz ama görünüşe göre
1952'den (1 s.); Ön sergi, 1952? (22 s., burada 20-22 s.
daha sonraki bir yedek olmak için); Kısa kod ek bilgileri, birinci konu (7 s.); ek
#1, 2, 3, 4 (9 s.).
Reppy, JH (1999) ML'de Eşzamanlı Programlama. Cambridge University Press, New York.
Richards, M. (1969) “BCPL: Derleyici Yazma ve Sistem Programlama için Bir Araç.” Proc.
AFIPS SJCC, Cilt. 34, s. 557–566.
Robinson, JA (1965) “Çözüm İlkesine Dayalı Makine Odaklı Bir Mantık.” Dergisi
ACM, Cilt. 12, s. 23–41.
Romanovsky, A. ve B. Sandén (2001) “İstisna İşleme Hariç,” Ada Letters, Vol. 21, No.3,
Eylül 2001, s. 19–25.
Roussel, P. (1975) “PROLOG: Manual de Reference et D'utilisation.” Araştırma raporu. Yapay
İstihbarat Grubu, Üniv. Aix-Marsilya, Luming, Fransa.
Rubin, F. (1987) “'GOTO Beyanı Zararlı Olarak Kabul Edildi' zararlı olarak kabul edildi” (editöre mektup).
Komün. ACM, Cilt. 30, No. 3, s. 195–196.
Rutishauser, H. (1967) ALGOL 60'ın Açıklaması. Springer-Verlag, New York.
Sammet, JE (1969) Programlama Dilleri: Tarih ve Temeller. Prentice-Hall, Engle-
ahşap Uçurumlar, NJ.
Sammet, JE (1976) “1974–75 için Programlama Dilleri Listesi.” Komün. ACM, Cilt. 19,
12, s. 655–669.
Schneider, DI (1999) Visual BASIC 6.0 Kullanarak Programlamaya Giriş. çırak-salon,
Englewood Kayalıkları, NJ.
Schorr, H. ve W. Waite. (1967) “Çöp için Verimli Bir Makine Bağımsız Prosedürü
Çeşitli Liste Yapılarında Toplama. Komün. ACM, Cilt. 10, No. 8, s. 501–506.
Scott, DS ve C. Strachey. (1971) “Bilgisayar Dili İçin Matematiksel Bir Anlambilime Doğru.”
Bildirilerde, Bilgisayarlar ve Otomasyon Sempozyumunda, J. Fox (ed.). Politeknik Enstitüsü
Brooklyn Press, New York, s. 19-46.
Scott, M. (2000) Programlama Dili Pragmatikleri, Morgan Kaufman, San Francisco, CA.
Sebesta, RW (1991) VAX Structured Assembly Language Programming, 2e. Benjamin/Cummings,
Redwood Şehri, CA.
Sergot, MJ (1983) “Mantık Programlama için Kullanıcı Sorgulama Tesisi.” Entegre Etkileşimli
Computer Systems, P. Degano ve E. Sandewall (ed.). Kuzey Hollanda Yayıncılık, Amsterdam.
Shaw, CJ (1963) “JOVIAL'in Bir Belirtimi.” Komün. ACM, Cilt. 6, No. 12, s. 721–736.
Smith, JB (2006) Pratik OCaml. Apress, Springer-Verlag, New York.
Sommerville, I. (2005) Yazılım Mühendisliği, 7e. Addison-Wesley, Okuma, MA.

Sayfa 791
770
bibliyografya
Steele, GL, Jr. (1990) Common LISP The Language, 2. baskı. Dijital Baskı, Burlington, MA.
Stoy, JE (1977) Düz Anlambilim: Programlama Dili için Scott-Strachey Yaklaşımı
anlambilim. MIT Press, Cambridge, MA.
Stroustrup, B. (1983) “C'ye Sınıf Eklemek: Dil Evriminde Bir Alıştırma.” Yazılım-
Uygulama ve Deneyim, Cilt. 13, s. 139-161.
Stroustrup, B. (1984) “C'de Veri Soyutlama.” AT&T Bell Laboratuvarları Teknik Dergisi, Cilt. 63,
8.
Stroustrup, B. (1986) C++ Programlama Dili. Addison-Wesley, Okuma, MA.
Stroustrup, B. (1988) “Nesneye Yönelik Programlama Nedir?” IEEE Yazılımı, Mayıs 1988,
s. 10–20.
Stroustrup, B. (1991) C++ Programlama Dili, 2e. Addison-Wesley, Okuma, MA.
Stroustrup, B. (1994) The Design and Evolution of C++. Addison-Wesley, Okuma, MA.
Stroustrup, B. (1997) C++ Programlama Dili, 3e. Addison-Wesley, Okuma, MA.
Sussman, GJ ve GL Steele, Jr. (1975) “Scheme: An Interpreter for Extended Lambda Calculus.”
MIT AI Memo No. 349 (Aralık 1975).
Suzuki, N. (1982) “İşaretçi 'Döndürme' Analizi' Komün. ACM, Cilt. 25, No. 5, s. 330–335.
Syme, D., A. Granicz ve A. Cisternino. (2010) Uzman F# 2.0. Apress, Springer-Verlag, New York.
Tanenbaum, AS (2005) Yapılandırılmış Bilgisayar Organizasyonu, 5e. Prentice Salonu, Englewood
Cliffs, NJ.
Tenenbaum, AM, Y. Langsam ve MJ Augenstein. (1990) C. Prentice-Hall Kullanan Veri Yapıları,
Englewood Kayalıkları, NJ.
Teitelbaum, T. ve T. Reps. (1981) “The Cornell Program Synthesizer: A Syntax-Directed Pro-
gramaj Ortamı.” Komün. ACM, Cilt. 24, No. 9, s. 563–573.
Teitelman, W. (1975) INTERLISP Referans Kılavuzu. Xerox Palo Alto Araştırma Merkezi, Palo Alto,
CA.
Thomas, D., C. Fowler ve A. Hunt. (2005) Ruby: Pragmatik Programcılar Kılavuzu, 2e, The
Pragmatik Kitaplık, Raleigh, NC.
Thompson, S. (1999) Haskell: İşlevsel Programlamanın El Sanatları, 2e. Addison-Wesley, Okuma,
MA.
Turner, D. (1986) “Miranda'ya Genel Bakış.” ACM SIGPLAN Bildirimleri, Cilt. 21, No. 12, s. 158–166.
Ullman, JD (1998) ML Programlamanın Unsurları. ML97 Sürümü. Prentice Salonu, Englewood
Cliffs, NJ.
van Emden, MH (1980) “Prolog'da McDermott: Bir Cevap.” SIGART Bülteni, Sayı 72,
Ağustos, s. 19–20.
van Wijngaarden, A., BJ Mailloux, JEL Peck ve CHA Koster. (1969) “Algo-
Ritmik Dil ALGOL 68.” Numerische Mathematik, Cilt. 14, No. 2, s. 79–218.
Wadler, P. (1998) “Neden Kimse İşlevsel Dilleri Kullanmıyor.” ACM SIGPLAN Bildirimleri, Cilt. 33,
2, Şubat 1998, s. 25-30.
Wall, L., J. Christiansen ve J. Orwant. (2000) Programlama Perl, 3e. O'Reilly ve Ortakları,
Sivastopol, CA.
Warren, DHD, LM Pereira ve FCN Pereira. (1979) “DEC System-10 için Kullanıcı Kılavuzu
Prolog." Ara Sıra Bildiri 15. Yapay Zeka Bölümü, Üniv. Edinburgh'lu,
İskoçya.
Watt, DA (1979) “Pascal için Genişletilmiş Nitelikli Dilbilgisi.” ACM SIGPLAN Bildirimleri,
Cilt 14, No. 2, s. 60–74.
Wegner, P. (1972) “Viyana Tanım Dili.” ACM Bilgi İşlem Anketleri, Cilt. 4, 1 numara,
s. 5-63.
Weissman, C. (1967) LISP 1.5 Astar. Dickenson Press, Belmont, CA.
Wexelblat, RL (ed.) (1981) Programlama Dillerinin Tarihi. Akademik Basın, New York.
Wheeler, DJ (1950) “EDSAC için Program Organizasyonu ve İlk Siparişler.” Proc. R. Soc.
Londra, Ser. A, Cilt. 202, s. 573–589.
Wilkes, MV (1952) “Saf ve Uygulamalı Programlama.” ACM Ulusal Bildirilerinde
Konferans, Cilt. 2. Toronto, s. 121–124.

Sayfa 792
Kaynakça 771
Wilkes, MV, DJ Wheeler ve S. Gill. (1951) Elektronik için Programların Hazırlanması
EDSAC'a Özel Referans ve Bir Alt Program Kütüphanesinin Kullanımı ile Dijital Bilgisayar
dişler. Addison-Wesley, Okuma, MA.
Wilkes, MV, DJ Wheeler ve S. Gill. (1957) Elektronik için Programların Hazırlanması
Dijital Bilgisayar, 2e. Addison-Wesley, Okuma, MA.
Wilson, PR (2005) “Tek İşlemcili Çöp Toplama Teknikleri.” http://ww w adresinde mevcuttur.
.cs.utexas.edu/users/oops/papers.htm#bigsurv.
Wirth, N. (1971) “Programlama Dili Pascal.” Acta Informatica, Cilt. 1, No. 1,
s. 35–63.
Wirth, N. (1973) Sistematik Programlama: Bir Giriş. Prentice-Hall, Englewood Cliffs, NJ.
Wirth, N. (1975) “Programlama Dillerinin Tasarımı Üzerine.” Bilgi İşleme 74 (Pro-
IFIP Kongresi 74). Kuzey Hollanda, Amsterdam, s. 386-393.
Wirth, N. (1977) “Modula: Modüler Çoklu Programlama için Bir Dil.” Yazılım—Uygulama
ve Deneyim, Cilt. 7, s. 3-35.
Wirth, N. (1985) Modula-2'de Programlama, 3e. Springer-Verlag, New York.
Wirth, N. (1988) “Programlama Dili Oberon.” Yazılım—Uygulama ve Deneyim,
Cilt 18, No. 7, s. 671–690.
Wirth, N. ve CAR Hoare. (1966) “ALGOL'ün Gelişimine Katkı.” Komün.
ACM, Cilt. 9, No. 6, s. 413–431.
Wulf, WA, DB Russell ve AN Habermann. (1971) “BLISS: A Language for Systems Pro-
gramer." Komün. ACM, Cilt. 14, No. 12, s. 780–790.
Zuse, K. (1972) “Der Plankalkül.” 1945'te hazırlanan, Berichte der'de yayınlanan el yazması
Gesellschaft für Mathematik und Datenverarbeitung, No. 63 (Bonn, 1972); Bölüm 3, 285 s.
176–196, ss.

Sayfa 793
Bu sayfa bilerek boş bırakılmıştır

Sayfa 794
773
A
Mutlak adresleme
manuel, 207
işaretçiler ve, 297
ile ilgili sorunlar, 40, 42
Soyut hücreler, 209
soyut sınıflar
Ada, 561 -562
C++'da, 547
giriş, 529
Java'da, 555
Soyut veri türleri
için tasarım sorunları , 478 –479
kayan nokta as, 476
giriş, 474
Ada'da, 482 –485, 503–504
C++'da, 485– 490,
505– 506
C#'da, 497– 499
C# 2005, 509'da
Java'da , 496 –497, 506–509
Java 5.0'da , 506 –509
Objective-C'de , 490 –496
parametreli, 503 –509
sorun ayarlandı, 520 –521
Ruby, 499 -503
yığınlar için, 478
özeti, 517– 518
kullanıcı tanımlı , 476 –478
Soyut yöntemler , 529
Soyutlama
başlangıcı, 72 –73
BNF'de, 118
zorunlu programlamada
diller, 204
için destek, 14, 21
Tümce gövdesini kabul et , 595
Maddeleri kabul et , 595– 600
Erişim
derin ve sığ , 462 -466
yığınlara, 289
iç içe alt programlarda,
454– 460
engellemesiz senkronize, 612
alt program bağlantısında, 442
türler, 293
ACM (Bilgi İşlem Derneği
makine)
GAMM ve, 53 , 117
Grace Murray Hopper Ödülü
arasında, 480 , 536
Turing Ödülü, 672
Aktivasyon kaydı örnekleri ,
444– 445
dizin

Sayfa 795
774
dizin
Aktivasyon kayıtları , 444 – 445
Aktif alt programlar
özellikleri, 389
referans ortamlarında,
231
yığın dinamik yerel değişkenler
ve, 448
Oyuncu görevleri , 596
Gerçek parametreler , 392
Özel ciltleme , 418– 419
Ad hoc polimorfizm , 422
Ada
95 versiyonu. bkz. Ada 95
2005 versiyonu, 84– 85
soyut veri türleri,
482–485 , 503–504
rekabet senkronizasyonu,
599- 601
derleyici uygulaması,
25
eşzamanlılık, 21 , 594-603
devamı , 638 –639
işbirliği senkronizasyonu
içinde, 599
maliyeti, 17
, 81 –82 için tasarım süreci
kapsülleme yapıları,
482
değerlendirmesi, 83 –84
istisna işleme, 16,
636- 643
tarihi geçmişi, 81
saklanan bilgi,
482– 483
dile genel bakış, 82 –83
paketler, 512, 516
işaretçi türleri, 293
görevlerin öncelikleri , 601 –602
korunan nesneler , 602 –603
görev sonlandırma, 601
Ada 95
alt paketler, 562
dinamik bağlama , 561 –562
miras , 559 –560
giriş, 84 –85
nesne yönelimli programlama
içinde, 21 , 558-563
adresler
için alanlar, 687
basit alt programların,
443– 445
yığın dinamik yerel
değişkenler , 445 –449
değişkenler, 208
Protokollerin benimsenmesi, 551
Toplam değerler , 265
Ah, Al, 95
AI (yapay zeka)
giriş, 6
LISP, 47– 48, 50
MIT'de proje, 680
ALGOL 58
tasarım süreci , 53 –54
genel bakış, 54
rapor, 55
ALGOL 60
ALGOL 58'e karşı, 53– 55
BNF içinde, 117- 118
tasarım süreci , 55 –56
değerlendirmesi, 56 –58
tarihi geçmişi, 53
giriş, 4– 5, 52
genel bakış, 56
ALGOL 68
için tasarım süreci, 73
değerlendirmesi, 74 –75
dile genel bakış, 74
ortogonallik, 11, 73
ALGOL Bülteni, 55
takma adlar , 208
takma , 16
Tahsis , 214 , 532–533
Belirsiz gramerler , 122 –123
AND operatörleri, 333 –336
ve ardından operatörler, 15, 336
Anonim değişkenler , 290
ANSI (Amerikan Ulusal
Standartlar Enstitüsü)
Ada'da, 82
C'de, 78
Minimum TEMEL standart,
64
Öncüller , 149 , 731-732
APES sistemi, 758
APL (Bir Programlama Dili)
dinamik dil olarak,
genel olarak, 71
giriş, 14 –15
kökenleri ve özellikleri,
71– 72
takaslar, 23
ekleme işlemleri, 747 –750
elma, 90
Tüm işlevsel formlara uygula , 676,
697– 698
APT (Otomatik Programlanmış
Araçlar), 22
aritmetik ifadeler
ilişkilendirilebilirlik , 321 – 323
zorlama , 330 –331
koşullu, 325
içindeki hatalar, 332
açık tür dönüşümleri ve,
331– 332
giriş, 319
LISP'de, 324
işlenen değerlendirme sırası,
319– 325
işlenen değerlendirme sırası,
325– 328
operatörün aşırı yüklenmesi ve
328- 329
parantez içinde , 323 –324
öncelik, 319 –321
Prolog'da, 743 –746
referans şeffaflığı,
327– 328
Ruby'de, 324
yan etkiler , 325 –328
tür dönüşümleri ve , 329 –332
dizi türleri
dizi başlatma , 264 –265
dizi işlemleri , 266 –267
kategoriler , 262 –264
için tasarım sorunları, 260

Sayfa 796
dizin 775
değerlendirmesi, 269
resmi parametreler, 394
uygulanması, 269 –272
indeksler ve , 260 –262
giriş , 259 –260
pürüzlü diziler , 267 –268
dikdörtgen diziler,
267– 268
dilimler , 268 –269
indis bağlamaları,
262- 264
Yapay zeka (AI). AI'ya bakın
(yapay zeka)
ASCII (Amerikan Standart Kodu
Bilgi Değişimi için),
249
Derlemeler , .NET, 512
iddialar
aksiyomatik anlambilimde,
148– 149
Java'da , 653 –654
atama ifadeleri
aksiyomatik anlambilimde,
150– 152
bileşik atama
operatörler, 337
koşullu hedefler ve, 337
düz anlambilimde, 146
ifadeler olarak , 339 –340
fonksiyonel programlamada
diller, 340 –341
giriş, 318
karma mod, 341
çoklu, 340
sorun ayarlandı, 343 –345
programlama alıştırmaları,
345– 346
inceleme soruları , 342 –343
basit, 336 –337
özeti, 341 –342
sözdizimi, 118 , 121–122, 127
tekli atama veri türleri
içinde, 338 –339
Bilgisayar Derneği
Makine (ACM), 53
ilişkisel diziler
uygulanması, 276
giriş, 272
yapısı ve işleyişi,
272– 276
Çağrışım , 126– 128,
321– 323
Atomik önermeler , 729
Atomlar , Prolog, 737
Nitelik hesaplama fonksiyonları ,
133
Özellik dilbilgisi
temel kavramları , 133 –134
öznitelik değerlerinin hesaplanması,
137– 138
tanımlanmış, 134
değerlendirmesi , 138 –139
örnekler, 135 –136
içsel nitelikler , 134 –135
giriş , 132 –133
statik anlambilim ve, 133
Öznitellikler
bağlama, 209 –210
tanımlanmış, 133
örnek verileri olarak, 501
içsel , 134 –135
Otomatik genelleme , 427
Otomatik programlama, 41
Otomatik Programlanmış Araçlar
(APT), 22
awk komut dosyası dili, 95
aksiyomatik anlambilim
iddialar , 148 –149
atama ifadeleri,
150– 152
değerlendirmesi , 160 –161
giriş, 148
mantıksal ön test döngüleri,
154– 158
program provaları, 158 –160
seçim , 153 –154
diziler , 152 –153
en zayıf ön koşullar,
149– 150
aksiyomlar , 149
B
B, dil, 77
Babbage, Charles, 82, 388
Geri izleme , 742
geri, John
Fortran, 20 , 41-43
işlevsel vs. zorunluluk üzerine
diller, 672 –673
sözdizimi hakkında, 117
Backus-Naur Formu (BNF) . görmek
BNF (Backus-Naur Formu)
Geriye zincirleme , 741– 742
temel önek, 557
TEMEL
tasarım süreci , 63 –64
değerlendirmesi, 64 –65
giriş, 18
zaman paylaşımı, genel olarak, 63
TEMEL-ARTI, 64
Bauer, Fritz, 53
BCD (ikili kodlu ondalık sayı) , 248
Bell Laboratuvarları. AT&T Bell'i görün
Laboratuvarlar
BINAC bilgisayar , 40
ikili kodlanmış ondalık sayı (BCD) , 248
İkili operatörler, 319
İkili semaforlar , 589
bağlama
özel, 418 –419
değişkenlerin nitelikleri,
209- 210
derin, 418 –419
dinamik. bkz. Dinamik bağlama
dinamik tip, 212 –214
işleyiciler için istisnalar, Ada,
637– 638
işleyicileri istisnaları, C ++,
644
işleyiciler için istisnalar, Java,
648– 649
açık yığın dinamik değişkenler
içinde, 216 –218
örtük yığın dinamik
değişkenler, 218
giriş, 204

Sayfa 797
776
dizin
Bağlama (devamı)
ömrü , 214 –215
genel bakış , 209 –210
sığ, 418 –419
yığın dinamik değişkenler,
215- 216
statik tip , 211 –212
statik değişkenler, 215
depolama, 214 –215
alt simge , 262 –264
tip, 210 –214
Bağlama süresi , 209
BLISS, 6
Engellenen görevler, 584
bloklar
Ruby'de, 374
kapsam için , 220 –223
alt programlarda uygulanması,
460– 462
Blok - yapılandırılmış dil ,
56, 220
BNF (Backus-Naur Formu)
sözdizimini analiz etme, 169
listeleri tarif 119,
ifadeler, 145
Genişletilmiş, 129- 132
temelleri, 118 –119
if-then-else ifadeleri
içinde, 128 –129
giriş, 55 –57
statik anlambilim, 133
sözdizimi ve, 117 –118
Gövde paketleri , 482– 484
Böhm, Corrado, 350, 379
Boolean soyut veri türleri ,
497– 498
Boole veri türleri , 249
Boole ifadeleri, 332 –335, 340
boole tipi değişkenler, 92 , 255,
612
Borland JBuilder, 31
Aşağıdan yukarıya ayrıştırıcılar
giriş, 180
LR ayrıştırıcıları ve, 193 –197
için sorun , 190 –192
için kaydırma azaltma algoritmaları,
192– 193
Aşağıdan yukarıya çözünürlük , 741
Bağlı değişkenler , 682 –683
Sınırlı joker karakter türleri, 426
Sınırlar , 425 –426
Boks , 552
Genişlik öncelikli aramalar, 742
ifadeleri kırmak
korunan komutlar ve, 379
çoklu seçim ifadeleri
ve, 355– 358
kullanıcı konumlu döngü kontrolünde
mekanizmalar, 370 –371
Brinch Hansen, Per , 590 –591,
593– 594
İş uygulamaları, 5 -6
İş kaydı bilgisayarlaştırma.
bkz. COBOL
Byron, Augusta Ada, 82
Bayt kodu , 30
bayt işlenenler, 320, 331
C
C
soyutlama desteği, 14
derleyici uygulaması, 25
kapsülleme yapıları,
510– 511
değerlendirmesi, 78 –79
ifade, 15
tarihi geçmişi, 77 –78
dil kategorileri, 22
ortogonallik, 11
işaretçi türleri , 294 –295
popülaritesi, 3
taşınabilir sistem, genellikle, 77
önişlemciler, 30
sistem yazılımı, 6– 7
tip kontrolü, 15
yazılabilirlik, 13
C#
2005 sürümü, 509
soyut veri türleri,
497– 499, 509
montajlar , 512 –513
eşzamanlılık, 21
için tasarım süreci , 101 –102
dinamik bağlama , 557 –558
kapsülleme yapıları,
498
değerlendirmesi , 103 –104
olay işleme , 661 –664
bilgi gizleme , 498 –499
miras, 557
dile genel bakış , 102 –103
iç içe sınıflar, 558
.NET dili olarak, 101
nesne yönelimli programlama
içinde, 556 –558
genel bakış , 101 –104
dişler , 613 –618
C++
soyut veri türleri,
485- 490, 505-506
soyutlama desteği, 14
derleyici uygulaması
içinde, 25
inşaatçılar, 487
devamı , 644 –645
tasarım süreci , 88 –89
yıkıcılar, 487
dinamik bağlama , 544 –547
kapsülleme yapıları,
486, 511-512
değerlendirmesi, 89
istisna işleme, 16,
643– 647
zorunlu özellikler,
genel olarak, 88
bilgi gizleme, 486
miras , 539 –544
dile genel bakış, 89
ad alanları, 514 –515
nesne yönelimli programlama
içinde, 88 , 538-539,
547– 549
ortogonallik, 11 –12
işaretçi türleri , 294 –295
popülaritesi, 3

Sayfa 798
dizin 777
sistem yazılımı, 6
takaslar, 23
Çağrı zincirleri , 450
aramalar
yöntemin dinamik bağlanması,
566– 568
dolaylı , 419 –421
alt programın anlamı ,442
Cambridge Lehçesi , 679
Cambridge Üniversitesi, 77
Deve notasyonu, 205
Çam, 52
kanonik LR algoritması, 193
ARABA fonksiyonları , 687 –688,
691– 694
Vaka ifadeleri , 357 –359
Büyük/küçük harf duyarlılığı , 206
vaka ifadeleri, 75 , 359-361
yakalamak , 643 , 648-649
Kategori arayüzleri, 550
C tabanlı diller , 204 -206
CBL (Ortak İş
Dil), 59
CDE (Solaris Ortak Masaüstü
Çevre), 31
CDR işlevleri , 687 –688,
691– 694
Celes, Waldemar, 100
merkezi işlem birimleri (CPU'lar),
18– 19
CGI (Ortak Ağ Geçidi Arayüzü),
97, 99
zincir_offset , 455
Odalar, Craig, 548
karakter dizileri, 250 –251, 265
karakter sıra türleri, 255
Karakter dizisi türleri
için tasarım sorunları, 250
değerlendirmesi, 253
uygulanması, 253 –255
dize uzunluğu seçenekleri,
252– 253
dizi işlemleri , 250 –252
tip kontrolü , 302 –303
Kontrol edilen istisnalar , 650
Alt kitaplık paketleri , 562
Çocuk paketleri , 562
Chomsky, Noam, 117
Kilise, Alonzo , 675
Cii Honeywell/Bull dili, 82
Clark, KL, 737
Clarke, Los Angeles, 227
sınıf örneği kayıtları (CIR'ler) ,
566– 568
Sınıf yöntemleri , 527
Sınıf değişkenleri , 527
sınıflar
özet, 529, 547
türetilmiş, 526 , 540-544
istisnalar, 647
, 555 –556
arayüz özeti , 553 –555
kilitli, 616
yerel iç içe, 556
iç içe, 533 , 555-556, 558
ebeveyn, 526 –527
alt, 526
süper, 526
sarıcı, 530
Cümle formu , 350 –351, 731–732
Müşteriler , 477
Saatçi, WF, 753
CLOS (Ortak LISP Nesnesi
Sistem), 21, 701
Kapalı kabul maddeleri , 599
Kapalı dünya varsayımı, 754
Kapanışlar , 430 –432
KML (Eşzamanlı ML), 619
COBOL
derleyici uygulaması,
25
iş kayıtlarının bilgisayarlaştırılması
içinde, 58
tasarım süreci , 59 –60
değerlendirmesi , 60 –63
FLO-MATIC ve, 59
tarihi geçmişi, 59
giriş için 5- 6
Kod oluşturma işlevleri, ŞEMA,
698– 699
zorlamalar
aritmetik ifadelerde,
330– 331
prosedürün kaldırılması için, 74
tip kontrolünde, 302
Colmerauer, Alain, 79, 736
Sütun ana düzeni , 270
Ortak İş Dili
(CBL), 59
Ortak Ağ Geçidi Arayüzü (CGI),
97, 99
Ortak Orta Düzey Dil
(CIL), 512
Ortak LISP, 51- 52, 699-701
Ortak LISP Nesne Sistemi
(CLOS), 21, 701
Sıralı Haberleşme
Süreçler (CSP), 597
ACM'nin İletişimi, 55,
672
Uyumlu tipler , 302, 530
Yarışma senkronizasyonu
Ada, 599 -601
eşzamanlı olarak, genellikle,
589– 590
giriş , 581 –585
Java'da , 607 –608
monitörlerle, 591
semaforlu, 589 –590
Derleyici tasarımı, 4
Derleyici uygulaması , 24 -28
Tamamlanan görevler , 601
Karmaşık veri türleri, 248
Bileşik atama operatörleri ,
337
Bileşik terimler , 729
Bilgisayar mimarisi, 18– 20
eşzamanlılık
Ada'da, 594 – 603
C# iş parçacıkları , 613 –618
kategorileri , 579 –580
rekabet senkronizasyonu
içinde, 589 –591, 598-601,
607– 608
Eşzamanlı ML'de, 619

Sayfa 799
778
dizin
Eşzamanlılık (devam)
işbirliği senkronizasyonu,
586– 589, 591–592
işbirliği senkronizasyonu,
Ada, 599
işbirliği senkronizasyonu,
Java, 608 – 611
için tasarım sorunları , 585 –586
açık kilitler, Java 5.0,
612– 613
F#'da, 620 –621
işlevsel dillerde,
618– 621
Yüksek Performanslı Fortran'da,
621– 623
giriş , 21 , 576-581
Java iş parçacıklarında. Konuları görmek
dil tasarımı, 585
ileti geçiyor , 593 –594
monitörler , 591 –593
Multilisp'te, 618
çok işlemcili mimariler
içinde, 577 –579
engellemesiz senkronizasyon
içinde, 612
korunan nesneler , 602 –603
kullanma nedenleri , 580 –581
semaforlar, 586 –590, 607
ifade düzeyi , 621 –623
alt program düzeyi , 581 –586
konuları senkronize etme,
616– 617
senkronize mesaj geçişi
içinde, 593 –594
görev öncelikleri , 601 –602
görev sonlandırma, 601
iş parçacığı öncelikleri , 606 –607
Eşzamanlı Pascal, 591
Eşzamanlı ML (CML), 619
Koşullu ifadeler, 325 , 708
Koşullu hedefler, 337
Bağlaçlar , 738
EKSİLERİNİ işlev , 688 -694
Sonuçlar , 149 , 731-732
sabit sabitler, 233
Kısıtlı değişken değişkenleri ,
285– 287
Constraint_Error
istisnalar , 639 –642
Yapıcılar , 487
Bağlamdan bağımsız gramerler , 117 –118
Devam , 634 –635
Kontrol ifadeleri, 350
Kontrol akışı , 685 –686
Kontrol ifadeleri , 348
Kontrol yapıları , 349
Cooper, Alan, 66
Cooper, Jack, 82
İşbirliği senkronizasyonu
Ada'da, 599
eşzamanlılık , 586 –589
giriş , 581 –585
Java'da , 608 – 611
monitörlü , 591 –592
semaforlu, 586 –589
Eşyordamlar , 73 , 432–435
Dil maliyetleri, 16 – 18
Sayaç kontrollü döngüler, 363 ,
367– 368
Ada'da, 364
C tabanlı dillerde,
364– 366
işlevsel dillerde,
367– 368
Python'da , 366 –367
Cox, Brad, 90
CPU'lar (merkezi işlem birimleri),
18– 19
CSP (İletişim Sıralı
Süreçler), 597
Köri, Malcolm, 81
Körleme , 706
Prolog'u Kes, 752 –753
D
Dahl, Ole-Johan, 72 –73
Sarkan işaretçiler , 292 –293
Sarkan referanslar , 294
Veri soyutlama. bkz. Soyutlama
Veri üyeleri , 486 , 539
Veri yapıları , 371 –375
Veri tipleri
sıralamak. bkz. Dizi türleri
ilişkisel dizi , 272 –276
boole, 249
karakter , 249 –250
karakter dizisi , 250 –255
karmaşık, 248
ondalık, 248 –249
eşdeğerlik , 304 –308
kayan nokta , 247 –248
tam sayı , 246 –247
giriş , 12 , 244–246
LISP'de , 677 –678
liste , 281 –284
sayısal, 246 –249
sıralı , 255 –258
işaretçi , 289 –295, 297–302
ilkel , 246 –250
sorun ayarlandı , 314 –315
programlama alıştırmaları,
315- 316
rekor, 276 –280
referans , 290 , 295-302
gözden geçirme soruları , 312 –313
dize uzunluğu seçenekleri,
252– 253
dizi işlemleri,
250 252
güçlü yazma , 303 –304
özeti, 310 –311
teori ve , 308 –310
demet , 280 –281
birlik, 284 –289
Ölü görevler, 584
Kilitlenmeler , 585
Deallocation , 214 , 532-533
Ondalık veri türleri , 248– 249
Beyanname sırası , 223 –224
Bildirimsel diller , 728 ,
734– 735
beyan blokları, Ada, 263
Ayrıştırma ağaçlarının dekorasyonu , 137
Azaltma alanları, 687
Derin erişim , 462 –464

Sayfa 800
dizin 779
Derin ciltleme , 418 –419
Ertelenmiş referans sayımı ,
299– 300
Tanımlar
COBOL'de, 60
fonksiyonların , 682 –684
alt programlarda, 389 –391
Delegeler , 420 –421
silmek
ilişkisel dizilerde, 273
C++'da, 291– 293, 486
veri türleri, 263
kullanarak açık ayırma, 538
Delfi, 90
düz anlambilim
atama ifadeleri, 146
değerlendirmesi, 147
örnekler, 143 –145
, 145 –146'daki ifadeler
giriş , 142 –143
mantıksal ön test döngüleri, 147
programların durumu ve, 145
Savunma Bakanlığı (DoD),
59- 61, 81
bağımlılar, 601
Derinlik öncelikli aramalar, 742
Referans kaldırma işaretçileri, 291
Türevler , 119– 121
Türetilmiş sınıflar , 526 , 540–544
Türetilmiş türler , 306
Tanımlayıcılar , 245
TASARIM SORUNLARI
soyut veri türleri için,
478– 479
dizi türleri için, 260
karakter dizisi türleri için, 250
eşzamanlılık için , 585 –586
istisna işleme için , 633 –636
fonksiyonlar için , 428 – 429
yinelemeli ifadeler için, 363
çoklu seçim için
ifadeler, 354 –355
isimler için, 205
nesne yönelimli için
programlama, 529– 534
işaretçi türleri için, 290
alt programlar için, 396 –397,
413– 414
takaslar, 23
iki yönlü seçim için
ifadeler, 350
birleşim türleri için, 285
Yıkıcılar , 487
Elmas mirası, 531
Sözlükler , 99 , 273
Dijkstra, Edsger
tarafından korunan komutlar,
376– 379, 593
PL/I'de, 70
semaforlar, 586
senkronizasyon işlemlerinde,
591
Doğrudan sol özyineleme , 187
Ayrımcı sendikalar , 285– 287
Ayrık görevler , 581
elden çıkarmak , 298
DLL'ler (dinamik bağlantı kitaplıkları) , 67 ,
512
EŞ ZAMANLI yapılar, 45
do while deyimleri,
369- 370
Savunma Bakanlığı (Savunma Bakanlığı),
59- 61, 81
Nokta gösterimi , 278– 279
Çift kayan noktalı veri türleri ,
247
Dynabook, 86
dinamik bağlama
Ada 95'te , 561-562
C#'da, 557– 558
C++'da, 544 –547
giriş, 210
Java'da, 555
yöntemlere yapılan yöntem çağrılarının,
566– 568
Objective-C'de , 551 –552
nesne yönelimli programlamada,
527– 529, 533
Ruby'de, 565
Smalltalk'ta, 535
Dinamik zincirler , 450
Dinamik gönderme . bkz. Dinamik
bağlayıcı
Dinamik diller, 68– 71
Dinamik uzunluk dizileri ,
253– 255
dinamik bağlantı kitaplıkları (DLL'ler) , 67 ,
512
Dinamik bağlantılar , 446
Dinamik kapsam belirleme , 227– 229,
462– 466
dinamik anlambilim
aksiyomatik semantik olarak. görmek
aksiyomatik anlambilim
anlamsal anlambilim,
142– 147
giriş, 139
operasyonel semantik olarak,
139– 142
Dinamik tip ciltleme , 212– 214,
303, 569
Dinamik tip kontrolü , 303
E
İstekli yaklaşım , 299
EBNF (Genişletilmiş BNF), 129–132 ,
181– 182
ECMA (Avrupa Bilgisayarı
Üreticileri Derneği),
97
Edinburg sözdizimi , 737
Edwards, Daniel J., 680
Eich, Brendan, 97
Detaylandırma , 215
Element operatörleri , Fortran 95+,
266
Eliptik referanslar , 279
else-if yan tümcesi , 360 –361
kapsülleme yapıları
Ada'da, 482, 512, 516
C'de, 510 –511
C#'da, 498 , 512–513
C++'da, 486 , 511-512,
514– 515

Sayfa 801
780
dizin
Kapsülleme (devamı)
giriş, 474,
509- 510
Java'da, 515 –516
adlandırma, 513– 517
Objective-C'de , 490 –492
Ruby'de, 499 , 516–517
özeti, 517– 518
giriş maddeleri, 595
Numaralandırma sabitleri , 255
Numaralandırma türleri
C'de, 308
C#, 102
C++'da, 256, 258
tasarlama, 255 –257
değerlendirmesi , 257 –258
giriş, 255
Ortam işaretçileri (EP'ler),
442– 448
Alt program bağlantısının son sözü,
443– 448
EP'ler (Ortam işaretçileri),
442– 448
EQ? fonksiyonlar, 689 –690, 693
Denklik , 304– 308
Silme kuralı, 187
Hatalar
aritmetik ifadelerde, 332
atama ifadelerinde,
146– 147
özyinelemeli iniş ayrıştırıcılarında,
183– 184
Avrupa Bilgisayar Üreticisi-
ers Derneği (ECMA), 97
EVAL , 690 , 698–699
Değerlendirme ortamları , 702
Olay işleme
bibliyografik notlar, 665
C#'da, 661 –664
giriş , 630 , 655-656
Java'da, 656 – 660
özeti, 664– 665
Olay dinleyicileri , 657
Olaylar , 619, 655
İstisna işleme
Ada'da, 636 –643
temel kavramları , 631 –633
bibliyografik notlar, 665
C++'da, 643– 647
633 –636 için tasarım sorunları
giriş , 16 , 630-631
Java'da, 647 –655
özeti, 664– 665
İstisnalar , 332, 631
Nesnelerin münhasırlığı , 529 –530
Yürütülebilir görüntüler , 27
beklenen_tür, 136
Uzman sistemler, 757– 758
Açık beyanlar , 211
Açık yığın dinamik değişkenler ,
216– 218
Açık kilitler, Java 5.0 , 612 –613,
617
Açık tip dönüşümler ,
331– 332
İfade
aritmetik. bkz. aritmetik
ifade
olarak atama ifadeleri,
339- 340
Boole, 333– 335
düz anlambilimde,
145– 146
giriş, 318
karma mod, 330– 331
özyinelemeli iniş ayrıştırıcılarında,
182– 185
ilişkisel , 332 –333
kısa devre değerlendirmesi,
335– 336
özeti, 341– 342
için açık dilbilgisi,
125
Anlatımcılık, 14 -15
Genişletilmiş kabul maddeleri , 598
Genişletilmiş ALGOL, 6
Genişletilmiş BNF (EBNF), 129–132 ,
181– 182
Genişletilebilir Stil Sayfası Dili
Dönüşümler (XSLT), 22
dış niteleyiciler, 224
F
F #, 620- 621, 712-715
Olgu ifadeleri, 737 –738
Farber, JD, 72
Fatbarlar, 377
Özellik çokluğu , 9
Getir-yürüt döngüleri , 19
FGCS (Beşinci Nesil Hesaplama
Sistemler), 736
Alanlar , 277
Beşinci Nesil Bilgi İşlem
Sistemler (FGCS), 736
de Figueiredo, Luis Henrique,
100
filtre , 705
final , Java, 233 , 553–556
Sonuçlandırma, 635
sonlandırma yöntemleri, 553
nihayet maddeler, 612 , 652-653
Sonlu otomat , 171
Sonlu eşlemeler , 260
Firma zorlaması, 74
Birinci dereceden yüklem hesabı ,
729
Sabit yığın dinamik diziler , 262
Sabit yığın dinamik diziler , 262
esnek diziler, 74
batmadan yüzmek
C'de, 510
C#'da, 498
giriş, 15
tip kontrolünde , 302 –303
tür dönüşümlerinde , 329 –332
Kayan nokta veri türleri ,
247– 248, 476
Kayan nokta işlemleri, 42, 68
AKIŞ-MATIK, 59
FLPL (Fortran Liste İşleme
Dil), 48
Flynn, Michael J., 578

Sayfa 802
dizin 781
için tablolar
Ada'da, 364
C'de, 77 –78
C tabanlı dillerde,
364– 366
beyan emri ve, 224
tanımlı, 12
Plankalkül'de, 38
Python'da, 366 –367
kullanıcı konumlu döngü kontrolünde
mekanizmalar, 372– 373
foreach ifadeleri
dizi işlemede, 264
C#, 102
JSP'de, 106
.NET dillerinde, 373 –374
Form, 13, 205-206
Resmi parametreler , 391, 394
Fortran
soyutlama desteği, 14
Backus tasarımı, 20
için tasarım süreci, 43
değerlendirmesi, 45 –47
evrimi, genel olarak, 42
tarihi geçmişi, 42 –43
giriş, 4– 5
ad formlar, 205 -207
sürümleri, 14 , 43–45,
204– 207
Fortran Liste İşleme Dili
(FLPL), 48
İleri zincirleme , 741
FP (fonksiyonel programlama), 673
Özgür Yazılım Örgütü, 737
Ücretsiz sendikalar , 285
Tamamen atfedilen ayrıştırma ağaçları , 134
Tam nitelikli referanslar , 279
fonksiyonel bileşimler
giriş, 675
için operatörler, 714
Programda, 697
Fonksiyonel formlar , 675 –676,
696– 698
Fonksiyonel programlama (FP), 673
Fonksiyonel programlama dilleri
atama ifadeleri,
340– 341
bibliyografik notlar, 721
Ortak LISP as, 699– 701
eşzamanlılık , 618 -621
F# as, 712 –715
fonksiyonel formlar,
675– 676
temelleri, 676 –677
Haskell as , 707 –712
zorunlu diller
destekleyici, 715 –717
zorunlu diller vs,
717– 719
giriş , 672 –673
LISP olarak, 677– 680
matematiksel fonksiyonlar,
673– 676
ML olarak, 701– 707
olarak şema. bkz. Şema
basit fonksiyonlar , 674 –675
özeti, 720 –721
Fonksiyonlar
için tasarım sorunları , 428 –429
Şemada, 691– 694
yan etkileri , 428 –429
alt programlar olarak, 395– 396
Fonksiyonlar , 729
gelecekteki yapılar, 618
G
GAMM (Alman Derneği
Uygulamalı Matematik ve
Mekanik), 53
Çöp toplama , 299– 302
Gates, Bill, 66
Dillerin soykütüğü, 37
Genel Amaçlı Simülasyon
Sistem (GPS), 22
Genellik , 18
Oluştur ve test et , 753
Nesil , 116– 117
Jeneratörler , 709
Genel alt programlar
C# 2005, 427
C++'da, 423 –425
F#'da, 427 –428
giriş, 397,
422– 423
Java 5.0'da , 425 –426
Alman Uygulamalılar Derneği
Matematik ve Mekanik
(GAMM), 53
getPriority yöntemleri, 606
Alıcı yöntemleri, 564
Glennie, Alick E., 42 –43
Küresel kapsam , 224 –227
GNOME, 31
git, 91
Goller , 739– 740
Google, 91
Gosling, James, 92
git, 195– 197
GPSS (Genel Amaçlı
Simülasyon Sistemi), 22
gramer
belirsiz, 122– 123
bağlanmak. bkz. Özellik
gramer
bağlamdan bağımsız , 117 –118
türevler ve , 119 –121
LL gramer sınıfı,
187– 190
tanıyıcı ve, 132
net, 125 –129
van Wijngaarden, 74
Grafiksel kullanıcı arayüzleri (GUI'ler).
GUI'lere bakın (grafik kullanıcı
arayüzler)
Griesemer, Robert, 91
Griswold, RE, 72
Korunan komutlar , 376– 379, 593
Muhafızlar, 586
GUI'ler (grafik kullanıcı arayüzleri)
tanımlanmış, 655
Delphi'de, 90
UNIX ve, 31

Sayfa 803
782
dizin
H
Hammond, S., 758
Kollar , 191 –192
Harbison, Samuel P., 356
Hash'ler , 272– 273, 276
giriş, 96
Haskell, 707- 712
Başlı boynuz cümleleri , 734
Başlık dosyaları , 510– 511
Başsız boynuz cümleleri , 734
Yığın dinamik diziler , 263
Yığın dinamik değişkenler , 290
Yığınlar , 289
Ağır görevler , 581
Hejlsberg, Anders, 90, 101
Gizli eşzamanlılık , 579
Üst düzey işlevler , 675
Yüksek Dereceli Dil Çalışması
Grup (HOLWG), 81
Yüksek Performanslı Fortran (HPF),
621– 623
Hoare, ARABA
Ada'da, 83
dil tasarımı üzerine, 14, 23
geçen mesaj , 593 –594
monitörlerde, 591
Pascal, 75
HOLWG (Yüksek Dereceli Dil
Çalışma Grubu), 81
Hopper, Grace
adına ödül, 480, 536
derleme sistemleri, 41
programlama dilleri üzerine, 59
Korna cümleleri , 734
HPF (Yüksek Performanslı Fortran),
621– 623
HTML (Köprü Metni İşaretleme
Dilim)
giriş, 7, 22
JavaScript ve, 97– 98
JSP ve, 105
PHP ve, 99
XML ve, 104
Hursley Laboratuvarı, 69
Hibrit uygulama sistemleri ,
29– 30
Köprü Metni İşaretleme Dili
(HTML). HTML'ye bakın
(Köprü metni biçimlendirme
Dilim)
hipotezler , 734
Bence
IAL (Uluslararası Algoritmik
Dil), 54
IBM
APL tarafından geliştirilen, 71
Fortran tarafından geliştirildi, 42- 47
ortogonallik ve, 10
PL/I, 68 , 73–74 tarafından geliştirildi
PL/S tarafından geliştirilen, 6
UNIVAC “derleme” sistemi
ve, 41
“IBM Matematiksel
FORMÜL ÇEVİRİ
Sistem: FORTRAN” 43
kimlik türü, 551 –552
Tanımlayıcılar , 115, 204
Kimlik operatörleri, 320
IEEE Kayan Nokta Standardı,
247– 248
Yerusalimschy, Roberto, 100,
274– 275
Eğer mantıksal yapılar, 45
IF seçici işlevleri , 685 –686
if ifadeleri
ödevler ve, 340
bileşik ifadelerde,
351
Genişletilmiş BNF'de, 130
JSP, 105- 106
çoklu seçimde
ifadeler, 360 –362
yuvalama seçicilerinde , 351 –354
özyinelemeli iniş ayrıştırıcılarında,
181– 186
için kurallar, 119
seçici ifadelerde, 354
IFIP (Uluslararası
Bilgi İşlem), 75
if-then-else ifadeleri,
128–129 , 325
Zorunlu programlama
Diller
işlevsel diller
destekleyici, 715 –717
işlevsel diller vs.,
717– 719
giriş, 18
nesne yönelimli karma
diller ve. bkz. C++
uygulama yöntemleri
derleyici uygulaması,
24- 28
hibrit uygulama sistemleri,
29– 30
önişlemciler, 30
protokoller için, 551
saf yorum, 28
alt programlar için görmek
alt programlar ,
uygulamak
anlama, 4
Örtülü beyanlar , 211
Örtülü yığın dinamik diziler, 74
Örtülü yığın dinamik değişkenler ,
218
Gizli kilitler , 612 –613
ithalat beyannameleri , 515 –516
Mod parametre geçişinde , 400
içinde operatörler, 266
ifadeleri dahil et , 565
Artımlı işaret süpürme çöpü
koleksiyon, 301
Göstergeler, 74
Endeksler , 260– 262
çıkarım kuralları
değerlendirmesi , 160 –161
mantıksal ön test döngülerinde,
154– 158
program provalarında, 158 –160
sonuç kuralı olarak, 152

Sayfa 804
dizin 783
seçim ifadelerinde,
153– 154
sekanslarda , 152 -153
en zayıf ön koşullar ve,
149– 150
Çıkarım süreci , 740 –743
Infix operatörleri, 319
Bilgi gizleme
Ada'da, 482 –483
C#'da, 498 –499
C++'da, 486
Objective-C'de , 492-493
Ruby'de, 499
Miras
Ada'da, 559 – 560
C#'da, 557
C++'da, 539 –544
giriş , 525 –527
Java'da , 553 –555
Objective-C'de , 549 –551
Ruby'de, 565
Smalltalk'ta , 534 –535
Devralınan nitelikler , 134
İlk değerler, 363
Başlatma , 234 , 533–534
İç sınıflar , 555– 556
Inout modu parametre geçişi ,
400
Örnek veri depolama, 566
Örnek yöntemleri , 527
Örnek değişkenler , 527
Örnekleme , 733, 737
int
soyut veri türleri,
497– 498
C'de, 326
C++'da, 295
Java'da , 609 – 611
ML'de , 702– 704
engellemesiz senkronize
erişim, 612
tip kontrolünde , 302 –303
tür dönüşümlerinde , 329 –332
tekli eksi operatörü ve, 320
tam sayı
veri türleri , 246 –247
sıra türleri, 255
ayrılmış kelimeler, 206 -207
Arayüz soyut sınıfı , 553 –555
Kilitli sınıflar, 616
Uluslararası Algoritmik
Dil (IAL), 54
Uluslararası Enformasyon Federasyonu
masyon İşleme (IFIP), 75
Uluslararası standartlar
Kuruluş (ISO), 97, 249
Tercüman , 678 –681
içsel nitelikler , 134– 135
İç koşul kuyrukları , 608
İçsel sınırlamalar, 756
iPhone'lar, 90
IPL (Bilgi İşleme
Dil), 47- 49
olduğu operatörler, 266
ISO (Uluslararası Standartlar
Organizasyon), 97, 249
yinelemeli ifadeler
karşı kontrollü döngüler ve
363, 367-368
için veri yapıları , 371 –375
için tasarım sorunları, 363
giriş , 362 –363
mantıksal olarak kontrol edilen döngüler ve
368- 370
için ifadeleri, 364 -367
kullanıcı konumlu döngü kontrolleri,
370– 371
Iverson, Kenneth P., 71
J
Jacopini, Giuseppe, 350, 379
Pürüzlü diziler , 267– 268
JAR'lar (Java Arşivleri), 513
Java
soyut veri türleri,
496–497 , 506–509
iddialar , 653 –654
istisna sınıfları, 647
eşzamanlılık, 21
tasarım süreci , 91 –92
dinamik bağlama, 555
değerlendirmesi, 93 –94
olay işleme , 656 –660
istisna işleme, 16,
647– 655
ifade, 15
özellik çokluğu, 9
son cümlesi , 652 –653
zorunluluk temelli
nesne yönelimi, 91
miras , 553 –555
giriş, 12
JIT sistemleri, 30
iç içe sınıflar , 555 –556
nesne yönelimli programlama
içinde, 552 –556
genel bakış, 91 –94
paketler, 515 –516
parametreli soyut veri
içinde tipleri , 506 -509
popülaritesi, 3
GUI bileşenlerini içeri kaydırın,
656- 657
Konular . bkz. Konular
Java Arşivleri (JAR'lar), 513
Java Sunucu Sayfaları Standart Etiketi
Kitaplık (JSTL), 22 , 105–106
JavaScript
anonim işlevler,
715- 716
diziler, 264
dinamik tip bağlama,
213– 214
olay işleme, 656
evrimi, 97 –98
yürütme hızı, 718
örtük yığın dinamik
değişkenler, 218
lambda ifadeleri, 716
Lua vs., 101
iç içe işlevler , 220 –221
iç içe alt programlar, 454

Sayfa 805
784
dizin
PHP'ye karşı, 99
saf yorumlama, 28
ilişkisel operatörler, 333
JIT (Tam Zamanında). bkz. Just-in-
Zaman (JIT) derleyicileri
İşler, Steve, 90
birleştirme yöntemleri, 604– 606
KEYİF, 55
JSP 105- 106
JSTL (Java Sunucusu Sayfaları Standart
Etiket Kitaplığı), 22 , 105–106
Tam Zamanında (JIT) derleyicileri, 30
K
Kay, Alan, 85- 86
Kemeny, John, 63- 64
Kernighan, Brian, 95, 376
Anahtarlar , 272
Anahtar kelime parametreleri , 392
Anahtar kelimeler , 206
Knuth, Donald, 133 , 193–194
Korn, David, 95
Kowalski, Robert
mantık tabanlı semantik üzerine
ağlar, 758
Prolog, 79, 736
ksh komut dosyası dili, 95
Kurtz, Thomas, 63
L
Lambda hesabı , 675
Lambda ifadeleri
giriş, 675
JavaScript'te, 716
ML'de, 705
Şemada, 682, 695
dil tasarımı
Ada için, 81– 82
ALGOL 58, 53–54 için
ALGOL 60, 55–56 için
ALGOL 68, 73 için
TEMEL için, 63– 64
C# için, 101 –102
C++ için, 88 –89
kategoriler, 21 –23
COBOL için, 59– 60
bilgisayar mimarisi,
18– 20
değerlendirme kriterleri, 7 –18
Fortran için, 43
etkiler, 18 –21
Java için, 91 –92
LISP için, 48
için metodolojiler, 20– 21
PL/I için, 69
Prolog için, 79
SIMULA 67, 72–73 için
Smalltalk için, 85– 86
sözdizimi, 12 – 13
takaslar, 23
Dil üreteçleri, 116 –117
Dil tanıyıcıları, 116
Dil seçimi, 3
Laning ve Zierler sistemi, 43, 53
son ifadeler, 371
Tembel yaklaşım , 299
Tembel değerlendirme , 710– 712
LCF (Hesaplanabilir için Mantık
Fonksiyonlar), 52
Yeni diller öğrenmek, 3– 4
Sol faktoring , 189 –190
Sol özyinelemeli dilbilgisi kuralları , 128
Sol taraf (LHS)
aşağıdan yukarıya ayrıştırıcılarda, 180, 191
düz anlambilimde, 144
temelleri, 118– 123
dilbilgisi kuralları, 128
LL ayrıştırıcılarında , 187 –190
LR ayrıştırmada, 195
En soldaki türevler , 120 –121
Lerdorf, Rasmus, 98
İzin Vermek
beyan sırasına göre , 221 –223
F#'da, 712 –715
ML'de, 281
Seviye numaraları , 277
Lexemeler , 115- 116, 170-177
sözlüksel analiz
giriş , 25 –26,
168– 169
genel bakış , 169 –177
ayrıştırma. bkz. Ayrıştırma
özeti, 197– 199
Sözlüksel kapsam belirleme, 219
Ömür , 214– 215, 229–230
Hafif görevler , 581
Sınırlı dinamik uzunluk dizileri ,
253– 255
Sınırlı özel türler , 483
Bağlayıcılar , 27 , 444
Bağlantı , 27
Bağlama ve yükleme , 27
LISP
aritmetik ifadeler, 324
yapay zeka ve , 47 –48
Ortak, 51- 52
veri yapıları, 49 ,
677– 678
veri türleri , 677 –678
torunları, 51
için tasarım süreci, 48
değerlendirmesi, 50– 51
fonksiyonel programlama,
47– 50, 677
tercüman , 678 –680
giriş, 6
ilgili diller, 52
liste işleme ve, 47 –48
ortogonallik, 11
genel bakış, 49
Şema ve, 51
sözdizimi, 50
Liste anlama , 283
Liste işlevleri, Şema , 282 –283
Listeler
açıklamaları, 119
fonksiyonları , 686 –690
işleme, 47– 48
basit, 678 , 691-692
yapıları , 49 –50, 746–751
türleri , 281 –284
canlılık , 585
LL algoritmaları , 179
LL dilbilgisi sınıfı, 187– 190
Yük modülleri , 27

Sayfa 806
dizin 785
Yükleyiciler, 444
Yerel iç içe sınıflar , 556
Yerel referans ortamları,
397– 399
Yerel değişkenler , 218 , 397–399
local_offset , 450
Kilitler, 612 –613, 616–617
Kilitler ve anahtarlar yaklaşımı , 298
Hesaplanabilir Fonksiyonlar İçin Mantık
(LCF), 52
Mantıksal programlama dilleri
uygulamaları , 757 –758
bibliyografik notlar, 759
yan tümce formu , 731 –732
tanımlanmış, 728
uzman sistemler ve , 757 –758
giriş, 22 , 728
genel bakış , 734 –736
yüklem hesabı,
728- 734
problem seti , 760 –761
programlama alıştırmaları,
761
Prolog. prolog'a bakın
önermeler , 729 –731
ilişkisel veritabanı
Yönetim Sistemleri
ve, 757
özeti, 758 –759
teorem ispatlama , 732 –734
Mantıksal eşzamanlılık , 579
Mantıksal ön test döngüleri, 147 ,
154– 158
Mantıksal olarak kontrol edilen döngüler,
368- 370
uzun ilkel tür değişkenleri, 612
Döngü değişmezleri , 154 –158
Döngü parametreleri , 363
Döngü değişkenleri , 363 –364
döngüler
sayaç kontrollü , 363 –368
tanımlı, 362
mantıksal ön test , 147 , 154–158
mantıksal olarak kontrol edilen , 368 –370
kullanıcı konumlu , 370 –371
Kayıp yığın dinamik değişkenleri , 293
Aşk, Tim, 90
LR ayrıştırıcıları, 190 , 193–197
Lua
anonim işlevler, 390
diziler, 264 , 272, 276
numaralandırma türleri, 257
evrimi , 37 , 100–101
global değişkenler, 399
Ierusalimschy tarihinde , 274 –275
birden fazla atama, 340
iç içe alt programlar, 454
parametreler , 393 –395
kayıtlar, 278
ilişkisel operatörler, 333
seçim ifadeleri, 353
tablolar, 276
L değeri , 208 – 209
m
MAC OS X, 90
İşaretli çöp toplama,
299– 302
İşaretleme dilleri, tanımlı, 22
İşaretleme/programlama melezi
diller, 104 –106
Massachusetts Enstitüsü
Teknoloji (MIT). MIT'ye bakın
(Massachusetts Enstitüsü
teknoloji)
eşleşme ifadeleri, 288 , 362
Alt hedefler eşleştirme , 740
Eşleşen tip parametreleri, 644
Matematiksel fonksiyonlar,
673– 676
Matsumoto, Yukihiro, 100
Mauchly, John, 40
McCabe, FG, 737
McCarthy, John, 48 , 677-680
McCracken, Daniel, 23
Uysal zorlama, 74
Mellish, CS, 753
Üye işlevleri , 486, 539
Bellek hücreleri, 209
Bellek sızıntısı , 293
Mesaj arayüzleri , 526
Mesaj protokolleri , 526
Mesajlar
dinamik olarak bağlanır. görmek
dinamik bağlama
nesne yönelimli
programlama, 525– 527
geçen, 593 –594
MetaLanguage (ML), 52 ,
701- 707
Metadiller , 118
Metasemboller , 130
Yöntem çağrıları, 566 –568
Yöntemler , 526– 527, 566–568
Microsoft
C# tarafından, 101
JScript.NET tarafından, 97
.NET bilgi işlem platformu, 89
Visual BASIC, 66 –67
Visual Studio .NET tarafından, 31
Milner, Robin, 52
MIL-STD 1815, 82
MIMD (Çoklu Talimat
Çoklu Veri) bilgisayarlar, 578
Minsky, Marvin, 48
Miranda, 52
MIT (Massachusetts Enstitüsü
teknoloji)
AI Projesi, 48
LISP'de, 677
Şema, 51, 681
Karma mod ataması
ifadeler, 341
Karışık mod ifadeleri ,
330– 331
Karışımlar , 550
ML (MetaLanguage), 52,
701- 707
M-notasyonu, 678, 690
Modüller , 516 –517
Monitörler, 591 –593
MSDOS.exe, 66- 67
Çok noktaya yayın delegeleri , 421
çok noktalı, 618
Çok paradigma programlama, 536

Sayfa 807
786
dizin
Çoklu atama ifadeleri,
340
Çoklu kalıtım , 527 , 531-532
Çoklu Yönerge Çoklu-
Veri (MIMD) bilgisayarları,
578
Çoklu seçim ifadeleri
354 –355 için tasarım sorunları
örnekler, 355 –358
uygulanması, 358 –359
if , 360 –362 kullanarak
Çok işlemcili , 577– 579
Çok iş parçacıklı programlar, 579 –580
n
Ad türü eşdeğerliği , 305
Adlandırılmış sabitler , 232– 234
İsimler
için tasarım sorunları, 205
kapsülleme yapılarında,
513– 517
, I biçimli 205 -206
giriş , 204 –205
anahtar kelimeler, 206
ayrılmış kelimeler ve 206 -207
özel kelime , 206 -207
özeti, 234– 235
değişkenler, 208
değişkenlere karşı , 207 – 209
Daraltma türü dönüşümler , 329
Ulusal Fizik Laboratuvarı, 69
Doğal işlemsel anlambilim , 140
Naur, Peter, 55–56 , 117
NCC (Norveç Bilişim
Merkez), 72
Olumsuzlama problemi, Prolog,
754– 756
iç içe sınıflar
C#'da, 558
Java'da, 555 –556
nesne yönelimli
programlama, 533
İç içe liste yapıları, 49
İç içe alt programlar , 397 –399,
454– 460
Yerleştirme sınıfları , 533
Yuvalama seçiciler , 351 –354
yuvalama_derinliği , 455
.NET dilleri
montajlar , 512 –513
bilgi işlem platformu, 89
evrimi, 101
F# as, 712
giriş, 22
JIT sistemleri, 30
JScript.NET olarak, 97
Microsoft Visual Studio.NET
olarak, 31
programlama ortamları
ait 31
NetBeans, 31
Netscape, 97
von Neumann, John, 18
von Neumann mimarisi
zorunlu programlamada
diller, 204
giriş, 18– 19
LR ayrıştırmada, 195
von Neumann darboğazları , 27
yeni
nesnelerin tahsisinde, 532
C#'da, 498, 557
C++'da, 486
veri türleri, 263
yığın yönetiminde, 298
Java'da, 552
Ruby'de, 564
Yeni Programlama Dili
(NPL), 69
Newell, Allen, 47
NeXT , 90
sonraki yineleyiciler, 373
Sıfır değerler, 49, 289
Engellemeyen senkronizasyon, 612
Dönüştürmeyen döküm dönüşümleri,
304
yerel olmayan , 227
Kesin olmayan programlama dilleri,
710
Terminal olmayan semboller , 118, 122
Norveç Bilgi İşlem Merkezi
(KKK), 72
operatörler DEĞİL, 333 –334
operatörler değil , 755 –756
NPL (Yeni Programlama
Dil), 69
BOŞ , 691– 692
Sayısal veri türleri , 246– 249
Sayısal yüklem işlevleri, 685
Nygaard Kristen, 72- 73
Ö
Nesne dilimleme , 532 –533
Amaç-C
soyut veri türleri,
490– 496
C++ ve, 90
dinamik bağlama , 551 –552
kapsülleme yapıları,
490– 492
bilgi gizleme , 492 –493
nesne yönelimli programlama
içinde, 549 –552
Nesneye yönelik yapılar , 566 –568
Nesne yönelimli diller
nesnelerin tahsisi,
532– 533
içindeki nesnelerin serbest bırakılması,
532– 533
için tasarım sorunları , 529 –534
dinamik bağlama, 533
nesnelerin münhasırlığı,
529– 530
nesnelerin başlatılması,
533– 534
çoklu kalıtım,
531– 532
iç içe sınıflar, 533
tek miras , 531 –532
alt sınıflara karşı alt türler,
530– 531
Nesne yönelimli programlama
Ada, 558 -563
bağlama yöntemi çağrıları
yöntemler, 566 –568

Sayfa 808
dizin 787
C#'da, 556 –558
C++'da, genellikle , 538 –539,
547– 549
C++ dinamik bağlamada,
544– 547
C++ kalıtımda , 539 –544
alt paketler, 562
dinamik bağlama , 527 –529
miras , 525 –527
örnek veri depolama, 566
giriş, 21
Java'da , 552 –556
Objective-C'de , 549 –552
Ruby'de, 563 –565
Smalltalk'ta , 85 –87, 534–538
Stroustrup açık, 536
özeti, 569 –570
destek, genel olarak,
524– 525
nesneler
soyut veri türlerinde, 475
tanımlı , 245 –246
münhasırlık , 529 –530
başlatma , 533 –534
nesne yönelimli programda-
ming, genel olarak , 525 –526
OCaml, 52
Operand değerlendirme sırası,
325– 328
işlemsel anlambilim
değerlendirmesi, 142
giriş , 139 –140
süreci, 140
Operatör değerlendirme sırası,
319– 325
Operatör aşırı yüklemesi , 9 , 328–329
Operatör önceliği , 123 –126
Operatör öncelik kuralları , 320
Optimizasyon , 17
veya başka ifadeler, 336
VEYA operatörleri, 333 –336
Sıralı veri türleri
numaralandırma türleri , 255 –258
uygulanması, 259
tam sayı , 255
giriş , 125 –129, 255
alt aralık, 258 – 259
Ortogonallik , 9 –12, 73
diğerleri , 265 , 637
aksi halde , 708 , 711
Out modu parametre geçişi , 400
Çıkış fonksiyonları, 684
taşma , 332
Aşırı yüklenmiş değişmez değerler , 256 –257
Aşırı yüklenmiş operatörler , 328 –329
Aşırı yüklenmiş alt programlar , 397 ,
421– 422
Geçersiz kılınan yöntemler , 526 –527
geçersiz kılma komutları, 557– 558
P
Paket kapsamı , 515
Paket özellikleri , 482 –484
Paketler , 482– 485, 562
İkili ayrıklık testi , 188
Papert, Seymour, 86
Programlama paradigmaları,
536– 537
Parametre profilleri , 390
Parametreli soyut veri türleri
Ada'da, 503 – 504
C# 2005, 509'da
C++'da, 505 –506
giriş , 503 –509
Java'da , 506 –509
Parametre geçiş yöntemleri
ortak dillerden,
406– 408
örnekleri , 414 –417
uygulama modelleri,
400– 405
uygulanması , 405 – 406
giriş , 399 –400
semantik modelleri, 400
parametreler
çok boyutlu dizilerde,
410– 413
alt programlar için, 391 –395
alt programlar olarak, 417 –419
Parametrik polimorfizm , 423
parametreler , 393
Ebeveyn sınıfları , 526 –527
Parantezler, 323 –324
Ayrıştırma ağaçları , 25 , 121–122
ayrıştırma
aşağıdan yukarıya, 180 , 190-192
karmaşıklığı , 180 –181
giriş , 177 -178
LL dilbilgisi sınıfı,
187– 190
, 193 –197 için LR ayrıştırıcıları
problem seti , 200 –201
programlama alıştırmaları
üzerinde, 201
özyinelemeli iniş , 181 -187
ile ilgili soruları gözden geçirin,
199– 200
için kaydırma azaltma algoritmaları,
192– 193
özeti, 197 –199
yukarıdan aşağıya, 179
Kısmi doğruluk , 158
Kısmi değerlendirme , 706
paskal
Eşzamanlı, 591
atma operatörü, 293
numaralandırma veri türleri,
256
evrimi , 36 –37, 57,
75- 77
kilit ve anahtar yaklaşımı
içinde, 298
iç içe alt programlar, 399
parametre geçişi, 419
çalışma zamanı kontrolleri, 312
alt aralık türleri, 258
Turbo, 101
Geçiş ödevi , 408
Geçiş kopyası , 403
Geçiş - by - isim , 404 -405
Geçiş - ile - referans , 403 -404
Geçiş sonucu , 401 –403
Geçiş - by - değeri - Sonuç , 403
Geçen değer , 401
pcall yapıları, 618

Sayfa 809
788
dizin
PDA ( Pushdown otomatı ),
193
Perl
diziler , 261 –264
atamalar , 337 –341
ilişkisel diziler , 272 –276
ikili mantık operatörleri, 334
C#'a karşı, 103
dinamik uzunluk dizileri, 253
dinamik kapsam belirleme, 227 –228
evrimi, 36 –37
üs alma, 396
foreach ifadeleri, 380
hibrit sistem uygulaması,
30
zorunlu programlama olarak
dil, 22
genel bakış, 95– 97
parametre geçişi, 407
desen eşleştirme, 170, 252
önek operatörleri, 319
Python'a karşı, 99 –100
Ruby'ye karşı, 100
dilimler, 268
sonra ve başka maddeler, 350,
352
Unicode, 249
değişkenler, 205 , 211
Perlis, Alan, 46, 53
PHP
diziler, 273 , 276, 373
yürütme hızı, 718
foreach ifadeleri, 103
global değişkenler , 224 –225
genel bakış, 98– 99
parametre geçişi, 392, 407
desen eşleştirme, 252
saf yorumlama, 28
ilişkisel operatörler, 333
betik dili olarak, 7, 28
ifadeleri değiştir , 357
bağlama yazın, 213
değişken isimleri, 205
İfadeler , 191– 192
Fiziksel eşzamanlılık , 579
Turna, Rob, 91
boru hattı (|>) operatörleri, 714
Plankalkül, 38– 39
PL/I
tasarım süreci, 69
değerlendirmesi, 70 –71
tarihi geçmişi, 68
giriş, 68
dile genel bakış, 69 –70
operasyonel anlambilim, 142
genel bakış, 68– 71
PL/S, 6
İşaretçi türleri
Ada'da, 293
C ve C++'da, 294– 295
sarkan, 292 –293, 297–298
için tasarım sorunları, 290
değerlendirmesi, 297
yığın yönetimi ve
298– 302
giriş , 289 –290
kayıp yığın dinamik değişkenler
içinde, 293
operasyonlar , 290 –291
sorunlar, 291
temsilleri, 297
Polonsky, IP, 72
Polimorfik referanslar , 528
Polimorfik alt programlar ,
422– 423
Polimorfizm, 422– 423
Rio de Papalık Üniversitesi
Janeiro, 100, 274
Taşınabilirlik , 18
Taşınabilir sistem dilleri. C'ye bakın
Konumsal parametreler , 392
son koşullar
atama ifadelerinde,
150– 152
giriş , 148 –149
mantıksal ön test döngülerinde,
154– 158
program provalarında , 158 –160
seçim ifadelerinde,
153– 154
sekanslarda , 152 -153
en zayıf ön koşullar
ve. bkz. En Zayıf
ön koşullar
Sontest , 363
pragma , 601, 640
Öncelik, 319 –321
Hassasiyet , 247
ön koşullar
atama ifadelerinde,
150– 152
giriş , 148 –149
mantıksal ön test döngülerinde,
154– 158
program provalarında, 158 –160
seçim ifadelerinde,
153– 154
sekanslarda , 152 -153
en zayıf. bkz. En Zayıf
ön koşullar
yüklem hesabı
tanımlanmış, 729
mantıksal programlama için
diller, 728 –734
Prolog'da, 79
yüklem fonksiyonları , 134 ,
689– 691
Yüklem transformatörleri ,
154– 158
Önek operatörleri, 319
Önişlemciler , 30
ön test , 362
İlkel veri türleri
boole, 249
karakter, 249 –250
karmaşık, 248
ondalık, 248– 249
kayan nokta , 247 –248
tam sayı , 246 –247
sayısal, 246– 249
İlkel sayısal fonksiyonlar,
681– 682

Sayfa 810
dizin 789
Görevlerin öncelikleri , 601 –602
Konuların öncelikleri , 606 –607
özel
Ada'da, 562
C#'da, 498 –499
C++'da, 486 –487, 540–544
Ruby'de, 500 – 501
Özel tipler , 482– 484
Prosedür odaklı programlama,
21
Prosedürler, 395 –396
Süreç soyutlaması , 475
Süreçler , 581
Üretici-tüketici sorunları ,
582
Üretimler , 118
Program hesabı, 38
Program sayaçları , 19
Program kanıtları, 158 –160
Program_Error istisnaları,
639
Programlama tasarım metodolojisi
turlar, 20 –21
Programlama alanları
yapay zeka, 6
iş uygulamaları, 5– 6
genel olarak, 5
bilimsel uygulamalar, 5
sistem programlamada, 6– 7
Web yazılımı ve, 7
Programlama ortamları, 31
Prolog
aritmetik , 743 –746
kapalı dünya varsayımı, 754
eksiklikleri , 751 –756
tasarım süreci, 79
unsurları, genel olarak,
736- 737
değerlendirmesi, 80
olgu ifadeleri , 737 –738
gol ifadeleri , 739 –740
çıkarım süreci , 740 –743
içsel sınırlamalar, 756
giriş, 6
dile genel bakış, 79– 80
liste yapıları , 746 –751
mantık, genel olarak, 79
olumsuzlama problemi, 754 –756
kökenleri, 736
çözünürlük sipariş kontrolü,
751- 753
kural ifadeleri , 738 –739
terimler, 737
Prolog++, 21
Alt program bağlantısının önsözü,
443– 448
Özellikler, C#, 498– 499
Önermeler , 729– 731
korumalı erişim değiştiricileri, 498
Korunan nesneler , 592 , 602-603
Protokoller , 390, 551
Prototipler , 391
sözde kodlar
giriş, 39 –40
ilgili çalışma, 42
Kısa Kod, 40– 41
Hızlı kodlama, 41
UNIVAC “derleme” sistemi,
41
halka açık
C#'da, 498
C++'da, 486
türevler , 540 –544
Ruby'de, 500 – 501
Saf yorum, 28
Saf sanal işlevler , 546
Saf sanal yöntem, 529
Pushdown otomatı ( PDA ), 193
piton
diziler , 264 –268
karmaşık değerler, 248
eşzamanlılık, 585
def ifadeleri, 390
sözlükler, 273
elif ifadeleri, 360
ifadeleri yorumlama, 681
lambda ifadeleri, 716
uzun tamsayı türü, 246
değişken listeler , 283 –284, 311
iç içe alt programlar, 219,
454, 510
genel bakış, 99 –100
parametreler, 392 –394
geçiş ödevleri, 408
desen eşleştirme, 252
referans ortamları ve,
230
dizeler, 251
alt programlar, 389
sonra ve başka maddeler, 351
demetler , 280 –281, 712
bağlama yazın, 213
Unicode, 249 –250
Q
Niceleyiciler, 730
Eşzamanlılık , 433
Yarı eşzamanlı alt programlar ,
579– 580
Sorgular , 739– 740
QUOTE , 686- 687
r
Yarış koşulları , 582
radyo düğmeleri
C#'da, 661 –664
Java'da , 656 – 660
ifadeleri yükseltmek , 640
Yükseltilmiş istisnalar , 631
RAND Şirketi, 47
Menzil
diziler için, 284
kayan noktalı veri türlerinde,
247
yineleyiciler, 372
Python'da, 367
Ham yöntemler, 425
RDBMS'ler (İlişkisel veritabanı
yönetim sistemleri), 757
İfadeleri oku , 630
Okunabilirlik, 8, 16
Okuyucu makroları, 701

Sayfa 811
790
dizin
Okuyucular, 701
okuma-değerlendirme-yazdırma döngüleri (REPL'ler),
681
salt okunur sabitler, 233 –234
Hazır görevler, 583
Gerçek tipler, 703
Tanıma , 116
Kayıt türleri
kayıtların tanımı,
277– 278
değerlendirmesi, 279
uygulanması, 279 –280
giriş , 276 –277
, 278 –279'daki alanlara referanslar
Dikdörtgen diziler , 267– 268
Özyineleme, 449 –453
Özyinelemeli kurallar , 119
Özyinelemeli iniş ayrıştırıcılar
LL dilbilgisi sınıfı,
187– 190
genel bakış , 181 -187
aşağı itme otomatları olarak,
193
referans tipi, F#, 620
Referans sayaçları , 299
Referans parametreleri, 406
Referans türleri
sarkan işaretçiler ve,
297– 298
yığın yönetimi ve
298– 302
uygulanması, 297
giriş , 289 –290
genel bakış , 295 –297
temsilleri, 297
Referans ortamları ,
230- 232
Referans şeffaflığı ,
327– 328, 676–677
Reddetme tamamlandı , 733
Normal ifadeler , 252
Normal gramerler, 117
Normal diller , 171
İlişkisel veri türleri , 332– 333
İlişkisel veritabanı yönetimi
sistemler (RDBMS'ler), 757
İlişkisel ifadeler , 332– 333
İlişkisel operatörler , 332– 335
Güvenilirlik, 15
Randevu , 594 –597
tekrar, 19
REPL'ler (okuma-değerlendirme-yazdırma döngüleri),
681
Rapor Program Üreticisi (RPG),
22
Ayrılmış kelimeler , 206– 207
sıfırla, 373
Çözünürlük
aritmetik hesaplama,
743– 746
kapalı dünya varsayımı,
754
tanımlı, 732
, 746 –751 için liste yapıları
sipariş kontrolü , 751 –753
Prolog'da , 740 –743, 751–753
Özgeçmişler , 433 –434
Devam , 634
Döndürülen değerler, 429
İade, 442
ters fonksiyonlar, 364, 750
Richards, Martin, 77
Sağ özyinelemeli dilbilgisi kuralları ,
128
Sağ taraf (RHS)
aşağıdan yukarıya ayrıştırıcılarda, 180, 191
düz anlambilimde,
143– 144
türevler ve, 121
Genişletilmiş BNF'de, 130 –132
temelleri, 118– 123
dilbilgisi kuralları, 128
LL ayrıştırıcılarında , 187 –190
LR ayrıştırmada, 195
özyinelemeli iniş ayrıştırıcılarında,
182– 184
yukarıdan aşağıya ayrıştırıcılarda, 179
Ritchie, Dennis, 77 –78, 91, 376
Romanovski, İskender, 643
van Rossum, Guido, 99
Roussel, Phillippe, 79 , 736
Satır ana düzeni , 270
RPG (Rapor Programı
Jeneratör), 22
yakut
soyut veri türleri,
499- 503
aritmetik ifadeler, 324
dinamik bağlama, 565
evrimi, 67 , 100
miras, 565
modüller, 516 –517
nesne yönelimli programlama
içinde, 563 –565
Sonuç kuralı , 152
Kurallar , 118- 119, 739-740
çalışma yöntemleri, 603- 604
Çalışan görevler, 584
Çalışma zamanı yığınları , 447
Russell, Stephen B., 680
R değeri , 209
S
Sanden, Bo, 643
Tatmin edici alt hedefler , 740
Ölçeklenebilir algoritmalar, 577
Zamanlayıcılar , 583
şema
tüm fonksiyonel formlara uygula
içinde, 697 –698
kod oluşturma işlevleri,
698– 699
kontrol akışı , 685 –686
fonksiyonları tanımlama,
682– 684
örnek, 691 –694
fonksiyonel bileşimler,
697
fonksiyonel formlar , 696 –698
işlevsel dil olarak, 681
tercüman, 681
LET , 694 –695

Sayfa 812
dizin 791
LISP, 51
liste fonksiyonları , 686 –689
sayısal yüklem işlevleri
içinde, 685
kökenleri, 681
çıkış fonksiyonları, 684
yüklem fonksiyonları , 689 –691
ilkel sayısal fonksiyonlar,
681– 682
sembolik atomlar ve listeler,
689– 691
kuyruk özyinelemeli fonksiyonlar,
695– 696
Schwartz, Jules I., 55
Bilimsel uygulamalar, 5
Dürbün
için bloklar , 220 –223
için beyan emri , 223 –224
dinamik kapsam belirleme, 227– 229
küresel, 224– 227
giriş, 204
ömür boyu ve , 229 –230
adlandırılmış sabitler ve,
232– 234
genel bakış, 218
referans ortamları ve,
230- 232
statik kapsam belirleme , 219 –220, 227
özeti, 234– 235
Scott, Dana, 147
Komut dosyası dilleri, 95 –101
Komut Dosyaları , 95
ifadeleri seçin , 597 –599
Seçim, 153 -154
seçim ifadeleri
sayaç kontrollü döngüler, 363
giriş, 350
çoklu seçim , 354 –362
iki yönlü, 350– 354
Seçici ifadeler, 354
Anlamsal alanlar , 142
anlambilim
aksiyomatik. bkz. aksiyomatik
anlambilim
bibliyografik notlar,
161- 162
anlamsal. bkz. Düz anlam
anlambilim
dinamik, 139
giriş , 113 –115
doğal operasyonel, 140
operasyonel , 139 –142
statik, 133
yapısal operasyonel, 140
alt program çağrılarının ve
döner, 442
özeti, 161
sözdizimi ve. sözdizimine bakın
Semaforlar , 586– 590, 607
Cümleler , 115
Cümle biçimleri , 120
Diziler, 152 –153
Sergot, MJ, 758
Sunucu görevleri , 596
Servlet kapları , 105
Setter yöntemleri, 564
S-ifadeleri, 680
Sığ erişim, 464 –466
Sığ cilt , 418– 419
PAYLAŞ, 53–55 , 68–69
Paylaşılan miras , 531
Shaw, JC, 47
Kaydırma azaltma algoritmaları , 192– 193
Kısa Kod, 40– 41
kısa işlenenler, 320, 331
Kısa Menzil Komitesi, 60
Kısa devre değerlendirmesi , 335– 336
Yan etkiler , 325– 328, 428–429
SIGPLAN Bildirimleri, 82
SIMD (Tek Yönerge
Çoklu Veri) bilgisayarlar, 578
Simon, Herbert, 47
Basit atama ifadeleri,
336– 337
Basit işlevler, 674 –675
Basit listeler , 678 , 691–692
Basit ifadeler , 191– 192
Sadelik, 8 -9, 13-14
SIMULA 67
veri soyutlama, 72
tasarım süreci, 72 –73
giriş, 21
dile genel bakış, 73
nesne yönelimli programlama
içinde, 525
Tek miras , 527,
531– 532
Tek Komutlu Çoklu Veri
(SIMD) bilgisayarlar, 578
Tek boyutlu hücreler , 299
uyku yöntemleri, 605
Dilimler , 250 , 268–269
küçük konuşma
tasarım süreci, 85 –86
dinamik bağlama, 535
değerlendirmesi, 87
miras , 534 –535
giriş, 21
dile genel bakış, 86 –87
nesne yönelimli programlama
içinde, 85 , 525, 534–538
SNOBOL, 71– 72
Solaris Ortak Masaüstü
Çevre (CDE), 31
Kaynak diller , 25
özel , 52
Özel kelimeler, 12 , 206-207
Hızlı kodlama, 41
SQL (Yapılandırılmış Sorgu Dili),
757
Yığın dinamik diziler , 56, 262
Yığın dinamik yerel değişkenler ,
445- 453
Yığın dinamik değişkenler ,
215- 216
Stanford Üniversitesi, 75
başlatma yöntemleri, 604
Başlangıç ​​sembolleri , 119
Durum diyagramları , 171
Programların durumu, 145
İfade düzeyinde eşzamanlılık,
621– 623

Sayfa 813
792
dizin
İfade düzeyinde kontrol yapıları
hakkında sonuçlar , 379 –380
karşı kontrollü döngüler,
367– 368
korunan komutlar, 376– 379
giriş , 2 –3, 347–349
yinelemeli ifadeler , 362 –363,
371– 375
mantıksal olarak kontrol edilen döngüler,
368- 370
seçim ifadeleri, 350
için tablolar, 364- 367
özeti, 380
iki yönlü seçim ifadeleri,
350– 354
koşulsuz dal
ifadeler, 375 –376
Statik atalar , 219
Statik diziler , 262
Statik bağlama , 210, 533
Statik zincirleme , 454– 460
Statik uzunluk dizileri , 252– 255
Statik bağlantılar , 454– 455
statik değiştiriciler, 263
Statik ebeveynler , 219
statik kapsam
değerlendirmesi, 227
genel bakış , 219 –220
işaretçiler, 455
Statik anlambilim , 133
Statik tip bağlamalar , 211 –212
Statik değişkenler
bağlamada, 215
dinamik kapsam belirlemede, 229
giriş, 13
iç içe alt programlarda, 398
statik_derinlik , 455
Steele Jr., Guy L., 356
Steelman gereksinimleri belgesi,
82
adım boyutu , 363
dikiş Matematik Merkezi,
99
Depolama bağlamaları, 214 –215
Storage_Error istisnaları, 639
Strachey, Christopher, 147
Strawman gereksinimleri belgesi,
81– 82
Katı programlama dilleri,
710
Güçlü yazma , 303– 304
Stroustrup, Bjarne
C++ üzerinde, 480– 481
C++ ile, 88
programlama paradigmaları üzerine,
536– 537
yapılar
C, 308, 310'da
C#, 102
C tabanlı dillerde, 38
veri türü, 277
giriş, 11
Yapısal işlemsel anlambilim ,
140
Yapı tipi denkliği , 305
Yapılandırılmış Sorgu Dili (SQL),
757
Yapılar , 737
Alt sınıflar , 526 , 530–531
Alt hedefler , 740
Alt program çağrıları , 389
Alt program tanımları , 389
Alt program başlıkları , 389
Alt program bağlantısı , 442
Alt program düzeyinde eşzamanlılık,
581– 586
alt programlar
C# 2005, 427
C++'da, 423– 425
dolaylı arama , 419 –421
özellikleri , 388 –389
kapatma , 430 –432
eşyordamlar, 432 –435
, 389 –391'deki tanımlar
için tasarım sorunları , 396 –397,
413– 414
F#'da, 427 –428
olarak işlev görür , 395 –396,
428– 429
temelleri, 388
genel, 422– 428
uygulanması. görmek
alt programlar ,
uygulamak
giriş, 388
Java 5.0'da , 425 –426
yerel referans ortamları
için, 397 –399
yerel değişkenler , 397 –399
çok boyutlu diziler ve
410– 413
iç içe, 397 –399
aşırı yüklenmiş, 421 –422
parametre geçişi. bkz.
parametre geçiren
yöntemler
parametreler olarak, 417 –419
için parametreler , 391 –395
sorun kuruldu, 438 –439
prosedürler, 395 –396
döndürülen değerler ve, 429
fonksiyonların yan etkileri,
428– 429
özeti, 435– 436
tip kontrol parametreleri,
408– 410
kullanıcı tanımlı aşırı yüklenmiş veri
türler, 430
Alt programlar , uygulama
bloklar , 460 –462
aramalar, 442
derin erişim , 462 –464
dinamik kapsam belirleme,
462– 466
giriş, 442
iç içe alt programların,
454– 460
özyinelemeli , 451 –453
geri döner, 442
sığ erişim , 464 –466
basit alt programların,
443– 445
yığın dinamik yerel değişkenler
için, 445 –453
için statik zincirleme , 454 –460

Sayfa 814
dizin 793
özeti, 466
özyinelemesiz , 449 –451
Alt aralık türleri
tasarlama , 258 –259
değerlendirmesi, 259
giriş, 258
Alt simge bağlamaları , 262 –264
Abonelikler , 258
Alt dize referansları , 250
alt tür numaralandırma türü , 258
Alt tip polimorfizmi , 422
Alt türler , 306 , 530–531
Güneş Mikrosistemleri, 92
Süper
Java'da, 553
Objective-C'de, 550
sözde değişkenler, 535
Ruby'de, 564
Süper sınıflar , 526
Bastır Pragma , 640
Swing GUI bileşenleri, 656 –657
değiştirmek
C'de, 77 –78
C#'da, 376
çoklu seçim ifadeleri
ve, 355 –358
Sembolik atomlar ve listeler,
689– 691
Sembolik mantık , 729
senkronizasyon
Ada, 599 -601
eşzamanlılık , 586 –592
giriş , 581 –585
Java'da , 607 –608
değiştiricilerin sayısı, 93, 592
engelsiz, 612
ifadelerin, 608
diş sayısı , 616 – 617
Senkron mesaj geçişi,
593– 594
Sözdizimsel etki alanları , 142
Sözdizimi
belirsiz gramerler,
122- 123
analizi , 25 –27, 168–169
çağrışım , 126 –128
nitelik gramerleri ve. görmek
Özellik dilbilgisi
bibliyografik notlar,
161- 162
BNF ve, 117– 118
bağlamdan bağımsız gramerler ve
117- 118
türevler , 119 –121
tasarımı, 12 – 13
Genişletilmiş BNF'de, 129 –132
temelleri , 118 –119
nesil , 116 –117
gramer ve, 117– 121, 132
if-then-else ifadeleri,
128- 129
giriş , 113 –115
betimlemedeki sorunlar , 115 –117
LISP, 50
liste açıklamaları , 119
tanımlama yöntemleri, 117
operatör önceliği,
123– 126
ayrıştırma ve. bkz. Ayrıştırma
tanınması, 116
tanıyanlar, 132
anlambilim ve. bkz. anlambilim
özeti, 161 , 197-199
belirsiz gramerler,
128- 129
Sentezlenen nitelikler , 134
Siraküza Üniversitesi, 732
Sistem.Nesne , 102
Sistem programlama, 6– 7
Sistem yazılımı , 6
T
Etiketlenen türler , 559 –561
Kuyruk özyinelemeli fonksiyonlar,
695– 696
Görev tanımlayıcıları , 586
Göreve hazır kuyruklar , 584
görev özellikleri , 594 –595
Görev sonlandırma, 601
Tasking_Error istisnaları, 639
Görevler , 581– 585
Şablon işlevleri, 423
Terminal sembolleri , 118, 122
Terminal değerleri, 363
sonlandır , 599, 601
Şartlar , 737
Üçlü operatörler, 319
Testler , 709
Teksas A&M Üniversitesi, 480, 536
Metin kutuları, 656
sonra , 128– 129, 350
Teorem ispatlama, 732 –734
Veri türleri teorisi , 308 –310
Thompson, Ken, 91
İş Parçacığı
C++'da, 544
yarışma senkronizasyonunda,
607– 608
eşzamanlılık , 603 –604, 613
işbirliği senkronizasyonunda,
608– 611
tanımlanmış, 581
açık kilitler , 612 –613
Java'da, 93 , 606-607
engellemesiz senkronizasyonda,
612
öncelikleri , 606 –607
semaforlar, 607
İplik sınıfı , 604 –606
Kontrol konuları , 579 –580
atma ifadeleri , 644 –651
Atılan istisnalar, 631
cümleler atar , 654
Jetonlar , 115 , 170–177
Mezar Taşları , 297 –298
Yukarıdan aşağıya ayrıştırıcılar , 179
Yukarıdan aşağıya çözünürlük , 741
Toplam doğruluk , 158
İzleme modelleri , 744 –745
kırpma, 74
Tripod, 66 –67
blokları dene , 612 , 614
cümleleri dene
C++'da, 643 –646
Java'da , 648 –653

Sayfa 815
794
dizin
Demetler, 280 –281
Turing makineleri, 678
Turner, David, 52
ikiler tamamlayıcısı , 247
İki yönlü seçim ifadeleri
yan tümce formları , 350 –351
için kontrol ifadeleri, 350
tasarım sorunları, 350
yuvalama seçicileri , 351 –354
seçici ifadeler, 354
tip
Ada numaralandırma türlerinde, 258
Ada denkliği , 306 –307
Ada birlik türlerinde, 286, 289
F#'da, 287
ML'de, 281
Tür , tanımlı, 209
Tür bağlamaları
dinamik, 212– 214
giriş, 210
statik , 211 –212
Tip kontrolü
giriş, 15
genel bakış , 302 –303
parametreler, 408 –410
Tür dönüşümleri , 329 –332
tür numaralandırma türü , 257, 261
Tip denkliği , 304– 308
Yazım hataları , 303
Tip çıkarımı , 211
yazı tipi , 308
sen
Belirsiz gramerler, 123– 126
Tekli atama veri türleri,
338– 339
Tekli operatörler, 319
İşaretlenmemiş istisnalar , 650
Koşulsuz şube ifadeleri ,
375– 376
tanımsız , 145– 147
tanımsız , 264
Alt akış , 332
Ungar, David, 548
tek kod, 249
Birleşme , 733, 759
Örneklenmemiş değişkenler , 737
birlik , 285, 308
Birlik türleri
Ada'da, 285 –287
için tasarım sorunları, 285
ayrımcılığa karşı özgür sendikalar
içinde, 285
değerlendirmesi, 288
F#'da, 287 –288
uygulanması, 289
giriş, 284
Birim düzeyinde eşzamanlılık. görmek
alt program düzeyi
UNIVAC, 40– 41
UNIVAC Bilimsel Değişim
(KULLANIM), 53
Aix-Marsilya Üniversitesi, 79,
736
Edinburgh Üniversitesi, 79, 736
Utah Üniversitesi, 85
UNIX
programlama ortamı,
31
okunabilirliği, 13
sistem yazılımı, 6– 7
Sınırsız kapsam, 431
güvensiz , C#, 296
KULLANIM (UNIVAC Bilimsel
Değişim), 53
kullanım maddesi, 484, 516
Kullanıcı tanımlı
soyut veri türleri,
476– 478
sıralı veri türleri. bkz. Sıra
veri tipleri
aşırı yüklenmiş veri türleri, 430
Kullanıcı konumlu döngü kontrol mekanizması
nizm , 370– 371
yönergeyi kullanma , 515
V
val ifadeleri, 341 , 704–706
Değer , 209
Değer türleri , 290
var bildirimleri , 211 –212
Değişkenler
adresleri, 208
tanımlı, 245
isimleri, 208
isimler vs., 207 – 209
türü, 209
değeri, 209
Değişken boyutlu hücreler , 301
VAX mini bilgisayarlar, 10
VB (Görsel TEMEL), 13
VDL (Viyana Tanımı
Dil), 142
Vektör işlemciler , 578
Viyana Tanım Dili
(VDL), 142
sanal yöntem tabloları (vtables) ,
566– 568
sanal ayrılmış kelime,
545, 557
Görünür değişkenler , 218
Visual BASIC (VB), 13, 65–67
Görsel diller, 22
Visual Studio, 22, 31
geçersiz , 11 , 389-393
void * işaretçiler, 295
vtables (sanal yöntem tabloları) ,
566– 568
W
bekle semaforları, 586– 590
Duvar, Larry, 95
En zayıf ön koşullar
atama ifadelerinde,
150– 152
aksiyomatik anlambilimde,
149– 150
mantıksal ön test döngülerinde,
154– 158
sekanslarda , 152 -153
Web yazılımı, 7
Weinberger, Peter, 95
İyi tanımlanmışlık , 18
Wheeler, David J., 42
ne zaman maddeler, 598 –599

Sayfa 816
dizin 795
sırasında
ifadeler olarak atamalar için,
339
C#'da, 616
Java'da, 92 , 609
mantıksal olarak kontrol edilen döngülerde,
368- 370
döngüler, 154 –158
kısa devre değerlendirmelerinde,
335
özel kelime olarak, 12
sözdizimi , 114 –115
kullanıcı konumlu döngü kontrolünde
mekanizmalar, 371
Whitaker, Yarbay William, 81
Genişletme türü dönüşümleri , 329
Widget'lar, 655 –656
van Wijngaarden
gramer, 74
Joker karakter türleri, 426
Wileden, JC, 227
Wilkes, Maurice V., 42
Pencereler, 66- 67
Wirth, Niklaus, 75, 379
ile maddelerine
Ada'da, 484
Ada paketlerinde, 516, 562
Kurt, AL, 227
Woodman gereksinimleri
belge, 82
Sarıcı sınıfları, 530
Yazılabilirlik, 13, 16
x
Xerox Palo Alto Araştırma Merkezi
(Xerox PARC), 86
XML (Genişletilebilir İşaretleme
Dil), 104 –106
XSLT (Genişletilebilir Stil Sayfası
Dil Dönüşümleri),
22, 104–105
Y
yacc, 132
verim yöntemleri, 605
Z
Zuse, Konrad, 38

Orijinal metin